參考資料:1、 [美] 鄧恩(Dunn F.)著. 3D數學基礎——圖形設計與開發. 史銀雪,陳洪,王榮靜 譯 清華大學出版社 p57-65
2、http://www.2cto.com/kf/201311/260139.html
編程環境 QT4.8.4 + VS2010
本文用 C++實現一個簡單的Vector3類的功能,已經實現的功能有:
1、重載賦值運算符“=”
2、重載“==”和“!=”操作符
3、置爲零向量
4、重載一元運算符“-”
5、重載二元預算法“+”“-”
6、標量的乘除法
7、重載自反運算符
8、向量單位化
9、向量的數量積,又叫:點乘
10、向量的向量積,又加:叉乘
11、計算兩點間的距離
12、打印向量
程序清單
1、vector3.h
#ifndef VECTOR3_H
#define VECTOR3_H
class Vector3
{
public:
float x, y, z;
//構造函數
//默認構造函數,初始一個零向量
Vector3();
//複製構造函數
Vector3(const Vector3 &a);
//帶參數的構造函數,用三個值完成初始化
Vector3(float nx, float ny, float nz);
//析構函數
~Vector3();
//標準對象操作
//重載賦值運算符,並返回引用,以實現左值。
Vector3& operator=(const Vector3 &a);
//重載"=="操作符
bool operator==(const Vector3 &a) const ;
//重載"!="操作符
bool operator!=(const Vector3 &a) const ;
//向量運算
//置爲零向量
void Zero();
//重載一元"-"運算符
Vector3 operator-()const;
//重載二元"+"和"-"運算符
Vector3 operator+(const Vector3 &a) const;
Vector3 operator-(const Vector3 &a) const;
//標量的乘、除法
Vector3 operator*(float a) const;
Vector3 operator/(float a) const;
//重載自反運算符
Vector3& operator+=(const Vector3 &a);
Vector3& operator-=(const Vector3 &a);
Vector3& operator*=(float a);
Vector3& operator/=(float a);
//向量標準化
void Normalize();
//向量點乘,重載標準的乘法運算符
float operator*(const Vector3 &a) const;
//求向量模
float VectorMag(const Vector3 &a);
//計算兩向量的叉乘
Vector3 CrossProduct(const Vector3 &a,const Vector3 &b);
//計算兩點間的距離
float Distance (const Vector3 &a,const Vector3 &b);
//打印向量
void Vector3::PrintVector3();
};
#endif // VECTOR3_H
2、vector3.cpp
#include <iostream>
#include <qmath.h>
#include "vector3.h"
//默認構造函數,初始一個零向量
Vector3::Vector3(){
x=0;
y=0;
z=0;
}
//複製構造函數
Vector3::Vector3(const Vector3 &a){
x=a.x;
y=a.y;
z=a.z;
}
//帶參數的構造函數,用三個值完成初始化
Vector3::Vector3(float nx, float ny, float nz){
x=nx;
y=ny;
z=nz;
}
//析構函數
Vector3::~Vector3(){};
//標準對象操作
//重載賦值運算符,並返回引用,以實現左值。
Vector3& Vector3::operator=(const Vector3 &a){
x =a.x;
y =a.y;
z =a.z;
return *this;
}
//重載"=="操作符
bool Vector3::operator==(const Vector3 &a) const{
return x==a.x && y==a.y && z==a.z;
}
//重載"!="操作符
bool Vector3::operator!=(const Vector3 &a) const{
return x!=a.x || y!=a.y || z!=a.z;
}
//置爲零向量
void Vector3::Zero(){
x = y = z = 0.0f;
}
//重載一元"-"運算符
Vector3 Vector3::operator-()const
{
return Vector3(-x,-y,-z);
}
//重載二元"+"和"-"運算符
Vector3 Vector3::operator+(const Vector3 &a) const{
return Vector3(x+a.x,y+a.y,z+a.z);
}
Vector3 Vector3::operator-(const Vector3 &a) const{
return Vector3(x-a.x,y-a.y,z-a.z);
}
//標量的乘、除法
Vector3 Vector3::operator*(float a) const{
return Vector3(x*a,y*a,z*a);
}
Vector3 Vector3::operator/(float a) const{
float oneOverA = 1.0f /a;//注意這裏不對"除零"進行處理
return Vector3(x*oneOverA,y*oneOverA,z*oneOverA);
}
//重載自反運算符
Vector3& Vector3::operator +=(const Vector3 &a){
x+=a.x;
y+=a.y;
z+=a.z;
return *this;
}
Vector3& Vector3::operator -=(const Vector3 &a){
x-=a.x;
y-=a.y;
z-=a.z;
return *this;
}
Vector3& Vector3::operator *=(float a){
x *= a;
y *= a;
z *= a;
return *this;
}
Vector3& Vector3::operator /=(float a){
float oneOverA =1.0f/a;
x *= oneOverA;
y *= oneOverA;
z *= oneOverA;
return *this;
}
//向量標準化
void Vector3::Normalize(){
float magSq = x*x + y*y + z*z;
if (magSq >0.0f){//檢查除零
float oneOverMag = 1.0f / sqrt(magSq);
x *= oneOverMag;
y *= oneOverMag;
z *= oneOverMag;
}
}
//向量點乘,重載標準的乘法運算符
float Vector3::operator *(const Vector3 &a) const{
return x*a.x + y*a.y +z *a.z;
}
void Vector3::PrintVector3(){
std::cout <<"("<<x<<","<<y<<","<<z<<")"<<std::endl;
}
//求向量模
float Vector3::VectorMag(const Vector3 &a){
return sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
}
/*
Cross Product叉乘公式
aXb = | i j k |
| a.x a.y a.z|
| b.x b.y b.z| = (a.y*b.z -a.z*b.y)i + (a.z*b.x - a.x*b.z)j + (a.x+b.y - a.y*b.x)k
*/
//計算兩向量的叉乘
Vector3 Vector3::CrossProduct(const Vector3 &a,const Vector3 &b){
return Vector3(
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x
);
}
//計算兩點間的距離
float Vector3::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);
}
3、測試文件 main.cpp
#include <QtCore/QCoreApplication>
#include "vector3.h"
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//測試構造函數
Vector3 v1;
Vector3 v2(3.0f,4.0f,5.0f);
Vector3 v3(v2);
//測試賦值運算符
Vector3 v4 =v3;
//打印
v1.PrintVector3();
v2.PrintVector3();
v3.PrintVector3();
v4.PrintVector3();
//測試布爾運算 ==
if (v1 ==v3)
{
std::cout<<"v1=v3"<<std::endl;
}
else
{
std::cout<<"v1!=v3"<<std::endl;
}
if (v2 == v3)
{
std::cout<<"v2=v3"<<std::endl;
}
else
{
std::cout<<"v2!=v3"<<std::endl;
}
//測試布爾運算 !=
if (v1 !=v3)
{
std::cout<<"v1!=v3"<<std::endl;
}
else
{
std::cout<<"v1=v3"<<std::endl;
}
if (v2 != v3)
{
std::cout<<"v2!=v3"<<std::endl;
}
else
{
std::cout<<"v2=v3"<<std::endl;
}
//測試置爲零向量
v2.Zero();
v1.PrintVector3();
v2.PrintVector3();
v3.PrintVector3();
v4.PrintVector3();
//測試一元"-"運算符
Vector3 v5=-v3;
v5.PrintVector3();
//測試二元預算符
Vector3 v_x(2.0f,3.0f,4.0f);
Vector3 v_y(3.0f,3.0f,4.0f);
Vector3 v_add = v_x+v_y;
Vector3 v_sub = v_x-v_y;
v_add.PrintVector3();
v_sub.PrintVector3();
//求模
float mag = v2.VectorMag(v2);
std::cout <<mag<<std::endl;
//單位化
v2.Normalize();
v2.PrintVector3();
return a.exec();
}
二、運行結果
說明:本程序是在QT4.8.4 +VS2010中實現,如果轉到其他編程環境,請自行修改。