坐标
构建
使用默认构造函数会得到坐标原点,构建时需要输入浮点数。另外所有的几何都只支持输入浮点数,后续不再特殊说明。
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);
外积
== 和 !=
== 和 != 可用来对坐标/坐标各维度进行判断。
double result1 = crd1 == crd2;
std::cout << result1 << std::endl;
double result2 = crd1 != crd2;
std::cout << result2 << std::endl;
double result3 = crd1.Y() == crd2.Y();
std::cout << result3 << std::endl;
模
我们内核支持计算坐标的模长以及对坐标进行归一化。
模长
double length = crd1.Norm();
归一化
对坐标进行归一化有两种方式,一种不改变坐标本身,创建一个新的坐标,另一种则是直接改变坐标本身。
输出与输入
我们内核支持对坐标进行输出<<,也支持输入>>。
输出
std::cout << crd1 << std::endl;
输入
std::istringstream is("0.0 1.0 2.0");
is >> crd7;
点
构建
使用默认构造函数会得到原点。可直接创建或者基于 Coord3/Coord2 构建。
Coord3(三维点)
PointT< double, 3 > Point3
三维点
定义 PointT.hpp:459
Coord2(二维点)
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 = p2[1];
double z2 = p3[2];
更改
更改点某一维度的值可以使用如下两种方法。
p1.SetCoord(1.0, 0.0, 2.1);
p1.SetX(0.5);
p1.SetY(0.5);
p1.SetZ(0.5);
常用功能
运算
我们内核不支持对点做四则运算(加减乘除),事实上除 Coord 外,大部分几何都不支持四则运算,后续不再说明。但是如果需要对点做四则运算,可先获取点的 Coord ,然后再对 Coord 做运算。
const Coord3& crd3 = p1.Coord();
const Coord3& crd4 = p2.Coord();
const Coord3& crd5 = crd3 + crd4;
计算两点间的距离
double dis = p1.Distance(p2);
向量与方向
Vector3 即数学上的向量,有方向有长度。Direction3 只有方向,其模长必须为 1.0。
构建
std::cout << vec << ' ' << dir << std::endl;
std::cout << vec1 << ' ' << dir1 << std::endl;
std::cout << vec2 << ' ' << dir2 << std::endl;
std::cout << vec3 << std::endl;
VectorT< double, 3 > Vector3
三维向量
定义 VectorT.hpp:707
DirectionT< double, 3 > Direction3
三维方向
定义 DirectionT.hpp:587
获取与更改
与 Coord 类似,只不过 Direction 会自动归一化。
获取
获取向量/方向某一维度的值可以使用如下两种方法。
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:198
constexpr const Scalar & Y() const noexcept
获取 y 分量(仅当 DIM >= 2 时可用)
定义 DirectionT.hpp:190
constexpr const Scalar & X() const noexcept
获取 x 分量(仅当 DIM >= 1 时可用)
定义 DirectionT.hpp:182
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:128
void SetY(const OtherScalar &y)
设置方向的 y 分量,并进行标准化(仅当 DIM >= 2 时可用)
定义 DirectionT.hpp:140
void SetCoord(T &&... vs)
通过分量设置坐标,并进行标准化
定义 DirectionT.hpp:77
void SetZ(const OtherScalar &z)
设置方向的 z 分量,并进行标准化(仅当 DIM >= 3 时可用)
定义 DirectionT.hpp:152
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 没有。而内积、外积两者都是有的。用法与 Coord 类似。
加减
数乘
内积
double t = vecc.Dot(vec1);
double t2 = dirr.Dot(dir1);
外积
角度
内核支持计算角度,其中 Angle() 计算的是夹角,角度范围为 [0.0, pi];AngleWithRef() 计算的是 2d 上的转角,角度范围为 [-pi, pi],正负值取决于 ddir, other_dir, ref_dir 构成的是右手系还是左手系。
AMCAX::Direction3 ddir(1.0, 0.0, 0.0), other_dir(0.0, 0.5, 0.5), ref_dir(0.0, 0.0, 1.0);
double angle1 = ddir.Angle(other_dir);
double angle2 = ddir.AngleWithRef(other_dir, ref_dir);
注:在二维情况下只可以用 Angle() 来计算转角。
此外还可以判断是否反向 IsOpposite(),是否平行 IsParallel()。可参考以下代码:
bool op1 = v1.IsOpposite(v2, 0.1);
std::cout << op1 << std::endl;
bool pa1 = v1.IsParallel(v3, 0.1);
std::cout << pa1 << std::endl;
bool op2 = d1.IsOpposite(d2,0.1);
std::cout << op2 << std::endl;
bool pa2 = d1.IsParallel(d3, 0.1);
std::cout << pa2 << std::endl;
方向类,即单位向量
定义 VectorT.hpp:17
模
Vector 可以计算其模长和对其进行归一化,与 Coord 类似。
模长
double length = vec1.Norm();
归一化
轴
Axis3 是三维空间中的轴,等价于一个 Point3 加一个 Direction3。构建方法如下:
AxisT< double, 3 > Axis3
三维轴
定义 AxisT.hpp:423
此外内核支持计算轴的角度和模长。可参考以下代码:
double angle = axis.Angle(axis2);
标架
定义
Frame3 是三维空间中的标架,即点和 3 个互相垂直的方向。
世界坐标系{O;x,y,z}就是一个常用的标架,也是 Frame3 默认构造函数的标架:
constexpr const DirectionT< Scalar, DIM > & XDirection() const noexcept
获取 x 方向,仅当 DIM >= 1 时可用
定义 FrameT.hpp:449
constexpr const PointT< Scalar, DIM > & Location() const noexcept
获取位置
定义 FrameT.hpp:433
constexpr const DirectionT< Scalar, DIM > & YDirection() const noexcept
获取 y 方向,仅当 DIM >= 2 时可用
定义 FrameT.hpp:457
constexpr const DirectionT< Scalar, DIM > & Direction() const noexcept
获取三维主方向(z 方向)
定义 FrameT.hpp:441
FrameT< double, 3 > Frame3
三维标架
定义 FrameT.hpp:885
注:如果输入的 z 轴与 x 轴并不垂直,算法会用 z 外积 x 得到 y,再用 y 外积 z 得到 x。
左右手系
左图为右手系,右图为左手系(图中蓝、绿、红分别表示 x、y、z 轴),常用的局部坐标系为右手系。判断左右手系的方法是将右手的手指从 x 向 y 弯曲,如果大拇指与 z 方向一致就是右手系。
我们内核获取一个标架是否为右手系的方法是:
constexpr bool IsDirect() const noexcept
三维标架是否为右手标架
定义 FrameT.hpp:520
局部坐标系
标架可表示一个局部坐标系。局部坐标系的优势是可以将空间曲线曲面的构建简单化。
坐标平面
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:1102
旋转变换
constexpr double pi
数学常数 Pi,圆的周长与直径之比
定义 Constants.hpp:42
镜像变换
点镜像
轴镜像
平面镜像
等比例放缩变换
复合变换
复合变换的公式为sRx+b,其中,s为放缩因子,R为旋转矩阵,x为待变换的坐标,b为平移向量。
如构建如下变换:先绕x轴旋转pi/4,再缩放至0.2倍,最后沿x轴平移1个单位:
四元数的类
定义 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进行变换。