空间变换与计算_01_点与向量

前言

前面部分着重介绍了线性代数与空间变换的本质,其大部分是线性代数只是与三维空间计算原理的实际结合,其中大致包含:

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);
        /// destructor
        virtual ~point();

构造和析构一目了然,其中第五个构造是直接从三维空间的向量转成点,实际上,向量也可以看成原点到向量终点的连线,这样转换既符合常规思维,也方便使用。

点的计算部分如下:

        /// can be modified according to the index, range:[0,2].
        real& operator[](std::uint8_t index);
        /// only access.
        const 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:
        /// point data.
        real 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);
        /// only access.
        const 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 * vector.
        real 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 vector
        real length() const;
        /// return length and unit vector.
        real normalize();
        /// returns the unit vector.
        [[nodiscard]] vector normalized() const;
        /// return *this * vec.
        real 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 radian system.
        real radiansTo(const vector& vec) const;

如上面代码,功能分别为:

1、计算向量长度。

2、将向量单位化。

3、返回单位向量(不改变本身)。

4、两向量点乘。

5、两向量叉乘。

6、判断两个向量是否平行。

7、判断两个向量是否垂直。

8、求两向量夹角。

 

总结:

三维空间点和空间向量非常简单,计算也非常简单,这里不做过多细节介绍,其测试程序也非常简单,不做介绍,在后面空间计算的例子中,将会体现出这两部分的用法。

qySpace下载地址(github):qySpace

qySpace下载地址(csdn):qySpace

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值