前面部分着重介绍了线性代数与空间变换的本质,其大部分是线性代数只是与三维空间计算原理的实际结合,其中大致包含:
1、从复数到二维复平面计算。
2、从3x3矩阵到三维旋转的表示。
3、从4x4矩阵到三维空间的旋转、平移、缩放的表示。
掌握以上线性代数只是,基本能够自主开发一套三维空间位姿计算库,用于计算机中的三维显示计算,例如:医学导航、无人机集群姿态控制、虚拟现实、物理引擎等方面。
其中,前面章节缺乏对四元数的介绍,四元数能非常完美的表示三维空间的旋转,并且也能解决万向节锁死的问题。具备计算量小等特点。
这一板块将会介绍空间位姿计算的实际编写(C++),将会从最基本的点、向量到3x3矩阵、四元数、4x4矩阵及转换类的编写到每个类的测试用例的测试来介绍。本库采用右手直角坐标系,矩阵排列和opengl保持一致,其库也将兼容openggl、vtk等常用三维引擎。
我将会将此项目作为开源库共享(qySpace),其隶属于qytk个人库的一部分。在每一博文后,都将附上计算库的下载链接,将采用LGPLv3开源协议。
与VTK、ITK的设计不同,他们的设计使用了模板的方式,具有灵活性好,可变性高的特点,但这样往往使用起来不方便,代码量大、计算复杂。缺点例如:1、长度可变,往往长度大于3的点或者向量是我们不需要使用的,并且叉乘等运算只存在三维空间。2、使用麻烦、运算麻烦,填充每个分量需要单独设置,代码量大。
point的设计将直接使用长度为3的点,代表三维空间的一个点。其构造函数和析构函数如下:
/// constructor, [0.0, 0.0, 0.0] default.point();/// construct from another point.point(const point& pt);/// move constructor.point(point&& pt) noexcept;/// construct from xyz value.point(const real x, const real y, const real z);/// construct from pointer, there must be three values.point(const real* data);/// construct from vector, only copy data.point(const vector& vec);/// destructorvirtual ~point();
构造和析构一目了然,其中第五个构造是直接从三维空间的向量转成点,实际上,向量也可以看成原点到向量终点的连线,这样转换既符合常规思维,也方便使用。
点的计算部分如下:
/// can be modified according to the index, range:[0,2].real& operator[](std::uint8_t index);/// st real& operator[](std::uint8_t index) const;/// return true if not equal.bool operator!=(const point& pt) const;/// return true if equal, all values equal.bool operator==(const point& pt) const;/// operator=, from another point.point& operator=(const point& pt);/// move operator=.point& operator=(point&& pt) noexcept;/// operator=, from vector, only copy data.point& operator=(const vector& vec);/// operator+=, point += vector.point& operator+=(const vector& vec);/// operator-=, point -= vector.point& operator-=(const vector& vec);/// operator*=, point *= d, equivalent to extending along the origin.point& operator*=(const real d);/// operator/=, point /= d, equivalent to shortening along the origin.point& operator/=(const real d);/// operator+, return *this + vector.[[nodiscard]] point operator+(const vector& vec) const;/// operator-, return *this - vector.[[nodiscard]] point operator-(const vector& vec) const;/// operator*, return *this * d.[[nodiscard]] point operator*(const real d) const;/// operator/, return *this / d.[[nodiscard]] point operator/(const real d) const;
除上面之外,点还包括打印、获取是否合法(均为实数)、求两点距离、以及设置和获取点的每个分量值等。其点的数据如下:
private:/// al m_data[3];
也将不采用vtk、itk的模板方式,与点几乎相同,只是向量的计算部分与点有些差别。
vector的长度为3,代表三维空间的向量,其构造函数和析构函数如下:
/// constructor, [0.0, 0.0, 1.0] default.vector();/// construct from another vector.vector(const vector& vec);/// move constructor.vector(vector&& vec) noexcept;/// construct from xyz value.vector(const real x, const real y, const real z);/// construct from pointer, there must be three values.vector(const real* data);/// construct from point, only copy data.vector(const point& pt);/// construct from double point, from ptFirst to ptSecond, if same, Axis::Z.vector(const point& ptFirst, const point& ptSecond);/// destructor.virtual ~vector();
可以看出,与点的几乎一样,其中左后一个构造是通过两点构造,向量方向从ptFirst指向ptSecond。这里的向量与物理中的有区别,其只包含大小和方向,不包含作用点。在后续对库的补充中,将会加上这样的类似射线、线段、直线的数据结构,并提供相应的计算。
vector的计算部分如下:
/// can be modified according to the index, range:[0,2].real& operator[](std::uint8_t index);/// st real& operator[](std::uint8_t index) const;/// return true if not equal.bool operator!=(const vector& vec) const;/// return true if equal, all values equal.bool operator==(const vector& vec) const;/// operator=, from another vector.vector& operator=(const vector& vec);/// move operator=.vector& operator=(vector&& vec) noexcept;/// operator=, from point, only copy data.vector& operator=(const point& pt);/// operator+=, vector + vector.vector& operator+=(const vector& vec);/// operator-=, vector - vector.vector& operator-=(const vector& vec);/// operator*=, vector *= d, equivalent to extending vector.vector& operator*=(const real d);/// operator/=, vector /= d, equivalent to shortening vector.vector& operator/=(const real d);/// operator+, return *this + vector.[[nodiscard]] vector operator+(const vector& vec) const;/// operator-, return *this - vector.[[nodiscard]] vector operator-(const vector& vec) const;/// operator*, return *this * al operator*(const vector& vec) const;/// operator*, return *this * d.[[nodiscard]] vector operator*(const real d) const;/// operator/, return *this / d.[[nodiscard]] vector operator/(const real d) const;
其中,operator*(const vecor& vec)是点乘,与下面的dot函数一样。
/// return length of the vectorreal length() const;/// return length and al normalize();/// returns the unit vector.[[nodiscard]] vector normalized() const;/// return *this * al dot(const vector& vec) const;/// return *this x vec.[[nodiscard]] vector cross(const vector& vec) const;/// return true if parallel.bool isParallel(const vector& vec, const real errRadians = TOLERANCE) const;/// return true if vertical.bool isVertical(const vector& vec, const real errRadians = TOLERANCE) const;/// return the radians between *this and another vector, adopt al radiansTo(const vector& vec) const;
如上面代码,功能分别为:
1、计算向量长度。
2、将向量单位化。
3、返回单位向量(不改变本身)。
4、两向量点乘。
5、两向量叉乘。
6、判断两个向量是否平行。
7、判断两个向量是否垂直。
8、求两向量夹角。
三维空间点和空间向量非常简单,计算也非常简单,这里不做过多细节介绍,其测试程序也非常简单,不做介绍,在后面空间计算的例子中,将会体现出这两部分的用法。
qySpace下载地址(github):qySpace
qySpace下载地址(csdn):qySpace
本文发布于:2024-02-04 05:57:41,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170700504452878.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |