3D向量类

(1) 求负向量,a=(ax,ay,az). 负向量是(-ax,-ay,-az);

向量运算:

(2) 向量相加减,等于各分量相加减,a=(ax,ay,az), b=(bx,by,bz). a-b=(ax-bx,ay-by,az-bz);

(3) 标量与向量之间相乘和相除,等于各分量相乘除,k=2, a=(ax,ay,az). k*a=(kax, kay, kaz);

特殊操作:

(4) 向量标准化,  向量a除以本身的模长(大小),a / ||a||;

(5) 向量点乘, 向量a=(a1, a2, a3), b=(b1, b2, b3). 各分量相乘再求和,两个向量的相似性,

a\cdot b = \left \| a \right \|*\left \| b \right \|cos\theta =\sum_{i=1}^{3}a_ib_i

 一般是用分量相乘再求和;

(6) 向量叉乘, axb, 叉乘结果是个向量(y1z2-z1y2, z1x2-x1z2, x1y2-y1x2)

(7)  求向量模长,向量长度,大小,a=(ax,ay,az)

\left \| a \right \| = \sqrt{ax^2 + ay^2 + az^2}

(8) 两个向量之间的距离,a=(ax,ay,az), b=(bx,by,bz). 

dis(a,b) = \sqrt{(ax-bx)^2 + (ay-by)^2 + (az-bz)^2}

#include <iostream>
#include <algorithm>
#include <math.h>
 
// 3D 向量类
class Vector3 {
public:
    float x, y, z;
    // 构造函数
    Vector3() {};
    Vector3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {}
    // 复制构造函数
    Vector3(const Vector3 &a): x(a.x), y(a.y), z(a.z) {}
    
    // 标准对象操作
    // 重载"=="操作符
    bool operator ==(const Vector3& a) const
    {
        return a.x == x && a.y == y && a.z == z;
    }
    bool operator !=(const Vector3& a) const
    {
        return a.x != x || a.y != y || a.z != z;
    }
    
    // 向量运算
    // 置为0向量
    void zero() { x = y = z = 0.0f; }
    // 重载一元“-”运算符,求负向量
    Vector3 operator -() { return Vector3(-x, -y, -z); }
    // 重载二元“+”和“-”运算符,向量之间相加减
    Vector3 operator +(const Vector3& a)
    {
        return Vector3(a.x + x, a.y + y, a.z + z);
    }
    Vector3 operator -(const Vector3& a)
    {
        return Vector3(x - a.x, y - a.y, z - a.z);
    }
    // 重载二元“*”和“/”运算符,标量和向量之间相乘和相除
    Vector3 operator *(float a) const
    {
        return Vector3(a * x, a * y, a * z);
    }
    Vector3 operator /(float a) const
    {
        float one_over_a = 1.0f / a;  // 需对0检查
        return Vector3(one_over_a * x, one_over_a * y, one_over_a * z);
    }
    
    // 重载自反运算符,即会修改自身
    Vector3& operator +=(const Vector3& a) {
        x += a.x; y += a.y; z += a.z;
        return *this;
    }
    Vector3& operator -=(const Vector3& a) {
        x -= a.x; y -= a.y; z -= a.z;
        return *this;
    }
    Vector3& operator *=(float a) {
        x *= a; y *= a; z *= a;
        return *this;
    }
    Vector3& operator /=(float a) {
        float one_over_a = 1.0f / a;
        x *= one_over_a; y *= one_over_a; z *= one_over_a;
    }
    
    // 向量标准化: a / ||a||
    void normalize()
    {
        float dis = sqrt(x * x + y * y + z * z);
        if (dis > 0.0f)
        {
            float one_over_dis = 1.0f / dis;
            x *= one_over_dis;
            y *= one_over_dis;
            z *= one_over_dis;
        }
    }
    // 向量点乘,重载乘号: a.b = ||a|| * ||b|| * cosθ,或者分量相乘再求和。
    float operator *(const Vector3& a) const
    {
        return x * a.x + y * a.y + z * a.z;
    }
};
 
// 求向量模,即求向量长度
inline float vectorLen(const Vector3& a)
{
    return sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
}
// 计算两向量的叉乘: axb
inline Vector3 crossProduct(const Vector3& a, const Vector3& b)
{
    return Vector3(
        a.y*b.z - a.z*b.y,
        b.x*a.z - a.x*b.z,
        a.x*b.y - a.y*b.x
    );
}
// 重载“*”
inline Vector3 operator *(float k, const Vector3 &a)
{
    return Vector3(k * a.x, k * a.y, k * a.z);
}
// 两点距离
inline float distance(const Vector3& a, const Vector3& b)
{
    float dx = a.x - b.x;
    float dy = a.y - b.y;
    float dz = a.z - b.z;
    return sqrt(dx * dx + dy * dy + dz * dz);
}
// 提供一个全局0向量
extern const Vector3 kzeroVector;
 

猜你喜欢

转载自blog.csdn.net/jizhidexiaoming/article/details/131519160
今日推荐