坐标
构建
使用默认构造函数将得到原点坐标,另外构建时需要输入浮点数。注:所有的几何都只支持输入浮点数,后续不再特殊说明。
Coord3
Coord3d Coord3
三维坐标
定义 CoordT.hpp:2810
Coord2
Coord2d Coord2
二维坐标
定义 CoordT.hpp:2807
获取与更改
获取
获取坐标某一维度的值可以使用如下两种方法。
double x = crd.X();
double y = crd.Y();
double z = crd.Z();
double x2 = crd[0];
double y2 = crd[1];
double z2 = crd[2];
更改
更改坐标某一维度的值可以使用如下方法。
crd.SetX(0.5);
crd.SetY(0.5);
crd.SetZ(0.5);
常用功能
运算
支持加减,数乘,内积,外积,另外也支持 == 和 !=。
加减
数乘
内积
double t = crd1.Dot(crd2);
外积
== 和 !=
== 和 != 可用来对坐标/坐标各维度进行判断。
bool result1 = crd1 == crd2;
std::cout << result1 << std::endl;
bool result2 = crd1.Y() == crd2.Y();
std::cout << result2 << std::endl;
bool result3 = crd1 != crd2;
std::cout << result3 << std::endl;
bool result4 = crd1.Z() != crd2.Z();
std::cout << result4 << std::endl;
模长
double length = crd1.Norm();
归一化
对坐标进行归一化有两种方式:一种不改变坐标本身,创建一个新的坐标,另一种则是直接改变坐标本身。
输出与输入
内核支持对坐标进行输出<<,也支持输入>>。
输出
std::cout << crd1 << std::endl;
输入
std::istringstream is("0.0 1.0 2.0");
is >> crd7;
点
构建
可直接创建或者基于 Point3/Point2 构建。使用默认构造函数会得到原点。
Point3
PointT< double, 3 > Point3
三维点
定义 PointT.hpp:459
Point2
PointT< double, 2 > Point2
二维点
定义 PointT.hpp:456
获取与更改
获取
获取点某一维度的值可以使用如下两种方法。
double x = p1.X();
double y = p1.Y();
double z = p1.Z();
double x2 = p1[0];
double y2 = p1[1];
double z2 = p1[2];
更改
更改点某一维度的值可以使用如下两种方法。
p1.SetCoord(1.0, 0.0, 2.1);
p1.SetX(0.5);
p1.SetY(0.5);
p1.SetZ(0.5);
常用功能
运算
内核不支持对点做四则运算(加减乘除),事实上除 Coord 外,大部分几何都不支持四则运算,后续不再说明。但是如果需要对点做四则运算,可先获取点的 Coord ,然后再对 Coord 做运算。
计算两点间的距离
double dis = p1.Distance(p2);
向量与方向
Vector 有方向有长度,Direction 只有方向,其模长必须为 1.0。
构建
Vector3/Direction3
VectorT< double, 3 > Vector3
三维向量
定义 VectorT.hpp:707
DirectionT< double, 3 > Direction3
三维方向
定义 DirectionT.hpp:566
Vector2/Direction2
VectorT< double, 2 > Vector2
二维向量
定义 VectorT.hpp:704
DirectionT< double, 2 > Direction2
二维方向
定义 DirectionT.hpp:563
获取与更改
获取
获取向量/方向某一维度的值可以使用如下两种方法。
double x2 = vec[0];
double y2 = vec[1];
double z2 = vec[2];
double x4 = dir[0];
double y4 = dir[1];
double z4 = dir[2];
constexpr const Scalar & Z() const noexcept
获取 z 分量(仅当 DIM >= 3 时可用)
定义 DirectionT.hpp:171
constexpr const Scalar & Y() const noexcept
获取 y 分量(仅当 DIM >= 2 时可用)
定义 DirectionT.hpp:163
constexpr const Scalar & X() const noexcept
获取 x 分量(仅当 DIM >= 1 时可用)
定义 DirectionT.hpp:155
constexpr const Scalar & Y() const noexcept
获取向量的 y 坐标,仅当 DIM >= 2 时可用
定义 VectorT.hpp:158
constexpr const Scalar & Z() const noexcept
获取向量的 z 坐标,仅当 DIM >= 3 时可用
定义 VectorT.hpp:166
constexpr const Scalar & X() const noexcept
获取向量的 x 坐标,仅当 DIM >= 1 时可用
定义 VectorT.hpp:150
更改
更改向量/方向某一维度的值可以使用如下两种方法。
void SetX(const OtherScalar &x)
设置方向的 x 分量,并进行标准化(仅当 DIM >= 1 时可用)
定义 DirectionT.hpp:101
void SetY(const OtherScalar &y)
设置方向的 y 分量,并进行标准化(仅当 DIM >= 2 时可用)
定义 DirectionT.hpp:113
void SetZ(const OtherScalar &z)
设置方向的 z 分量,并进行标准化(仅当 DIM >= 3 时可用)
定义 DirectionT.hpp:125
DirectionT & SetCoord(T &&... vs)
通过分量设置坐标,并进行标准化
定义 DirectionT.hpp:77
constexpr void SetZ(const OtherScalar &z) &noexcept
设置向量的 z 坐标,仅当 DIM >= 3 时可用
定义 VectorT.hpp:117
constexpr void SetY(const OtherScalar &y) &noexcept
设置向量的 y 坐标,仅当 DIM >= 2 时可用
定义 VectorT.hpp:108
constexpr void SetCoord(T &&... vs) &noexcept
设置分量值设置坐标
定义 VectorT.hpp:81
constexpr void SetX(const OtherScalar &x) &noexcept
设置向量的 x 坐标,仅当 DIM >= 1 时可用
定义 VectorT.hpp:99
常用功能
运算
Vector 有加减、数乘,对应数学上的向量加减和数乘,Direction 没有。而内积、外积两者都是有的。
加减
数乘
内积
double t1 = vec2.Dot(vec1);
double t2 = dir2.Dot(dir1);
外积
角度
内核支持计算角度,其中 Angle() 计算的是夹角,角度范围为 [0.0, pi];AngleWithRef() 计算的是 2d 上的转角,角度范围为 [-pi, pi],正负值取决于三个 Vector/Direction 构成的是右手系还是左手系。
double angle1 = vec1.Angle(vec2);
double angle2 = vec1.AngleWithRef(other_vec, ref_vec);
double angle3 = ddir.Angle(other_dir);
double angle4 = ddir.AngleWithRef(other_dir, ref_dir);
注:在二维情况下只可以用 Angle() 来计算转角。
此外还可以通过 IsOpposite() 判断两向量/方向是否反向,通过 IsParallel() 判断两向量/方向是否平行。可参考以下代码:
bool op1 = v1.IsOpposite(v2, 0.1);
bool pa1 = v1.IsParallel(v3, 0.1);
bool op2 = d1.IsOpposite(d2, 0.1);
bool pa2 = d1.IsParallel(d3, 0.1);
方向类,即单位向量
定义 DirectionT.hpp:30
模长
double length = vec1.Norm();
归一化
轴
构建
轴等价于一个 Point 加一个 Direction。
Axis3
AxisT< double, 3 > Axis3
三维轴
定义 AxisT.hpp:423
Axis2
AxisT< double, 2 > Axis2
二维轴
定义 AxisT.hpp:420
常用功能
角度
内核支持计算轴与轴之间的角度。可参考以下代码:
double angle = axis1.Angle(axis2);
标架
定义
标架,即点和 3 个互相垂直的方向。
世界坐标系 {O;x,y,z} 就是一个常用的标架,也是 Frame3 默认构造出的标架:
constexpr const DirectionT< Scalar, DIM > & XDirection() const noexcept
获取 x 方向,仅当 DIM >= 1 时可用
定义 FrameT.hpp:451
constexpr const PointT< Scalar, DIM > & Location() const noexcept
获取位置
定义 FrameT.hpp:435
constexpr const DirectionT< Scalar, DIM > & YDirection() const noexcept
获取 y 方向,仅当 DIM >= 2 时可用
定义 FrameT.hpp:459
constexpr const DirectionT< Scalar, DIM > & Direction() const noexcept
获取三维主方向(z 方向)
定义 FrameT.hpp:443
FrameT< double, 3 > Frame3
三维标架
定义 FrameT.hpp:887
注:如果输入的 z 轴与 x 轴并不垂直,算法会用 z 外积 x 得到 y,再用 y 外积 z 得到 x。
左右手系
左图为右手系,右图为左手系,常用的局部坐标系为右手系。判断左右手系的方法是将右手四指从 X 轴向 Y 轴方向弯曲,若大拇指指向 Z 轴正方向,则该坐标系为右手系,否则为左手系。
我们内核获取一个标架是否为右手系的方法是:
constexpr bool IsDirect() const noexcept
三维标架是否为右手标架
定义 FrameT.hpp:522
局部坐标系
标架可表示一个局部坐标系。局部坐标系的优势是可以将空间曲线曲面的构建简单化。
坐标平面
XOY 平面
可以通过如下两种方式构造一个标准 XOY 平面。
std::cout << frame1.
Direction() << std::endl;
std::cout << frame1.
Location() << std::endl;
std::cout << frame2.XDirection() << std::endl;
std::cout << frame2.YDirection() << std::endl;
std::cout << frame2.Direction() << std::endl;
std::cout << frame2.Location() << std::endl;
static AMCAX_API const Frame3 & XOY() noexcept
获取以 z 轴方向为主要方向的坐标系
YOZ 平面
可以通过如下两种方式构造一个标准 YOZ 平面。
std::cout << frame4.
Direction() << std::endl;
std::cout << frame4.
Location() << std::endl;
std::cout << frame5.XDirection() << std::endl;
std::cout << frame5.YDirection() << std::endl;
std::cout << frame5.Direction() << std::endl;
std::cout << frame5.Location() << std::endl;
static AMCAX_API const Frame3 & YOZ() noexcept
获取以 x 轴方向为主要方向的坐标系
ZOX 平面
可以通过如下两种方式构造一个标准 ZOX 平面。
std::cout << frame7.
Direction() << std::endl;
std::cout << frame7.
Location() << std::endl;
std::cout << frame8.XDirection() << std::endl;
std::cout << frame8.YDirection() << std::endl;
std::cout << frame8.Direction() << std::endl;
std::cout << frame8.Location() << std::endl;
static AMCAX_API const Frame3 & ZOX() noexcept
获取以 y 轴方向为主要方向的坐标系
另外在应用中还会涉及到 Z 轴为负方向的 XOY 平面,X 轴为负方向的 YOZ 平面,Y 轴为负方向的 ZOX 平面。
Z 轴为负方向的 XOY 平面
std::cout << frame3_2.XDirection() << std::endl;
std::cout << frame3_2.YDirection() << std::endl;
std::cout << frame3_2.Direction() << std::endl;
std::cout << frame3_2.Location() << std::endl;
X 轴为负方向的 YOZ 平面
std::cout << frame6_2.XDirection() << std::endl;
std::cout << frame6_2.YDirection() << std::endl;
std::cout << frame6_2.Direction() << std::endl;
std::cout << frame6_2.Location() << std::endl;
Y 轴为负方向的 ZOX 平面
std::cout << frame9_2.XDirection() << std::endl;
std::cout << frame9_2.YDirection() << std::endl;
std::cout << frame9_2.Direction() << std::endl;
std::cout << frame9_2.Location() << std::endl;
变换
大部分几何都支持变换,即平移、旋转、镜像,等比例放缩变换等。
平移变换
形状的基类,包含具有位置和方向信息的基础形状
定义 TopoShape.hpp:15
TransformationT< double, 3 > Transformation3
三维变换
定义 TransformationT.hpp:1116
旋转变换
constexpr double pi
数学常数 Pi,圆的周长与直径之比
定义 Constants.hpp:42
镜像变换
点镜像
轴镜像
平面镜像
等比例放缩变换
复合变换
复合变换的公式为sRx+b,其中,s为放缩因子,R为旋转矩阵,x为待变换的坐标,b为平移向量。
如构建如下变换:先绕x轴旋转pi/4,再缩放至0.2倍,最后沿x轴平移1个单位:
double scale = 0.2;
四元数的类
定义 QuaternionT.hpp:19
将局部坐标系的物体变为全局坐标系(或另一坐标系)的变换
构建变换使得局部坐标系f2={O=(1,0,0), OZ=(1,1,0), OX=(0,0,1)}下的物体变换为全局坐标系下的物体:
将标架1平移、旋转到标架2的变换
构建变换使得全局坐标系的标架变换为另一标架f2={O=(1,0,0), OZ=(1,1,0), OX=(0,0,1)}:
变换的乘法
trans1 * trans2。先应用 trans2 变换,再应用 trans1 变换。