Files
ViewDesignEngine/include/vde/core/transform.h
T
茂之钳 a73c5e8954
CI / Build & Test (push) Failing after 1m31s
CI / Release Build (push) Failing after 32s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
fix(v1.0.1): VDE-002 submodule path + VDE-006 cycle dep + VDE-007/008/009 API fixes
VDE-002 (High): Fix submodule include path
- All target_include_directories: CMAKE_SOURCE_DIR → BUILD_INTERFACE
- Works as both standalone project and add_subdirectory()

VDE-006 (High): Break vde_mesh ↔ vde_brep circular dependency
- Move mesh-dependent code from brep to mesh module
- vde_brep no longer links vde_mesh

VDE-007 (Low): Add mirror() and mirror_about_plane() to transform.h

VDE-008 (Low): Add convenience accessors to StlTriangle (.x()/.y()/.z())

VDE-009 (Medium): Full Doxygen docs for C API + examples/capi/basic_usage.cpp

Pending: VDE-001/003/004/005/010 GCC compatibility (agent still running)
2026-07-27 22:29:06 +08:00

187 lines
4.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "vde/core/plane.h"
#include "vde/core/point.h"
#include <Eigen/Geometry>
namespace vde::core {
/**
* @brief 三维仿射变换类型
*
* 基于 Eigen::Transform,支持平移、旋转、缩放和它们的组合。
* 使用 4×4 齐次矩阵表示。
*
* @ingroup core
*/
using Transform3D = Eigen::Transform<double, 3, Eigen::Affine>;
/**
* @brief 创建平移变换
*
* @param v 平移向量
* @return 平移变换矩阵
*
* @code{.cpp}
* auto T = translate(Vector3D(1, 2, 3));
* Point3D p2 = T * Point3D(0,0,0); // p2 == (1,2,3)
* @endcode
*
* @ingroup core
*/
inline Transform3D translate(const Vector3D& v) {
return Transform3D(Eigen::Translation<double, 3>(v));
}
/**
* @brief 创建平移变换(分量形式)
*
* @param x X 方向位移
* @param y Y 方向位移
* @param z Z 方向位移
* @return 平移变换矩阵
*
* @ingroup core
*/
inline Transform3D translate(double x, double y, double z) {
return translate(Vector3D(x, y, z));
}
/**
* @brief 创建旋转变换(轴-角表示)
*
* @param axis 旋转轴(自动归一化)
* @param angle_rad 旋转角度(弧度)
* @return 旋转变换矩阵
*
* @code{.cpp}
* // 绕 Z 轴旋转 90°
* auto R = rotate(Vector3D::UnitZ(), M_PI / 2);
* @endcode
*
* @ingroup core
*/
inline Transform3D rotate(const Vector3D& axis, double angle_rad) {
return Transform3D(Eigen::AngleAxis<double>(angle_rad, axis.normalized()));
}
/**
* @brief 绕 X 轴旋转
*
* @param rad 旋转角度(弧度)
* @return 旋转变换矩阵
*
* @ingroup core
*/
inline Transform3D rotate_x(double rad) { return rotate(Vector3D::UnitX(), rad); }
/**
* @brief 绕 Y 轴旋转
*
* @param rad 旋转角度(弧度)
* @return 旋转变换矩阵
*
* @ingroup core
*/
inline Transform3D rotate_y(double rad) { return rotate(Vector3D::UnitY(), rad); }
/**
* @brief 绕 Z 轴旋转
*
* @param rad 旋转角度(弧度)
* @return 旋转变换矩阵
*
* @ingroup core
*/
inline Transform3D rotate_z(double rad) { return rotate(Vector3D::UnitZ(), rad); }
/**
* @brief 创建非均匀缩放变换
*
* @param sx X 方向缩放因子
* @param sy Y 方向缩放因子
* @param sz Z 方向缩放因子
* @return 缩放变换矩阵
*
* @note 非均匀缩放可能导致法线方向不准确;使用场景中应考虑法线变换 = (M^{-1})^T
*
* @ingroup core
*/
inline Transform3D scale(double sx, double sy, double sz) {
return Transform3D(Eigen::Scaling(sx, sy, sz));
}
/**
* @brief 创建均匀缩放变换
*
* @param s 各方向统一的缩放因子
* @return 缩放变换矩阵
*
* @ingroup core
*/
inline Transform3D scale(double s) { return scale(s, s, s); }
/**
* @brief 创建关于过原点平面的镜面反射变换
*
* 反射矩阵为 \f$ M = I - 2 \cdot \hat{n} \hat{n}^T \f$
* 其中 \f$ \hat{n} \f$ 是单位法向量。
*
* @param normal 平面法向量(自动归一化)
* @return 镜面反射变换矩阵
*
* @code{.cpp}
* // 关于 YZ 平面(法向量 X 轴)反射
* auto R = mirror(Vector3D::UnitX());
* Point3D p2 = R * Point3D(3, 1, 0); // p2 == (-3, 1, 0)
* @endcode
*
* @note 反射平面过原点,不能处理一般位置平面。使用 mirror_about_plane() 处理任意平面。
*
* @see mirror_about_plane
* @ingroup core
*/
inline Transform3D mirror(const Vector3D& normal) {
Vector3D n = normal.normalized();
Eigen::Matrix3d refl = Eigen::Matrix3d::Identity() - 2.0 * n * n.transpose();
Transform3D T;
T.linear() = refl;
T.translation().setZero();
return T;
}
/**
* @brief 创建关于任意平面的镜面反射变换
*
* 一般位置平面方程为 \f$ \hat{n} \cdot x + d = 0 \f$
* 反射变换为:
* \f[
* T = \begin{bmatrix} I - 2\hat{n}\hat{n}^T & -2d\hat{n} \\ 0 & 1 \end{bmatrix}
* \f]
*
* @param plane 反射平面(法向量自动归一化)
* @return 镜面反射变换矩阵
*
* @code{.cpp}
* Plane3D plane(Point3D(1, 0, 0), Vector3D::UnitX());
* auto R = mirror_about_plane(plane);
* // 点 (3, 0, 0) 到平面距离为 2,反射后变为 (-1, 0, 0)
* Point3D p2 = R * Point3D(3, 0, 0);
* @endcode
*
* @note 平面法向量在构造 Plane3D 时已归一化,无需额外处理。
*
* @see mirror
* @ingroup core
*/
inline Transform3D mirror_about_plane(const Plane3D& plane) {
const Vector3D& n = plane.normal();
double d = plane.d();
Eigen::Matrix3d refl = Eigen::Matrix3d::Identity() - 2.0 * n * n.transpose();
Transform3D T;
T.linear() = refl;
T.translation() = -2.0 * d * n;
return T;
}
} // namespace vde::core