3D数学 自定义三维向量类进行运算
2015-07-15 19:33
295 查看
3D数学 自定义向量类进行运算
设计一个3维向量类,可以实现如下运算:零向量
负向量
向量大小、长度、模
标量与向量的乘除法
单位向量
向量的加法和减法
距离公式
向量点乘
向量叉乘
由于原理很简单,所以不解释,下面给出全部源代码:
//Vector3.h #pragma once class Vector3{ public: Vector3(); Vector3(float X,float Y,float Z); //变为零向量 void Zero(); //求负向量 Vector3 operator-() const; //求向量大小(长度或模) float Length() const; //标准化该向量 void Normal(); //向量的加法 Vector3 operator+(Vector3 &rhs) const; Vector3& operator+=(Vector3 &rhs); //向量的减法 Vector3 operator-(Vector3 &rhs) const; Vector3& operator-=(Vector3 &rhs); //向量乘标量 Vector3 operator*(float scalar); //向量乘等于标量 Vector3& operator*=(float scalar); //向量除以等于标量 Vector3& operator/=(float scalar); //向量除以标量 Vector3 operator/(float scalar); //距离公式 float Distance(Vector3 &vec) const; //向量点乘 float operator*(Vector3 &rhs) const; //向量叉积 Vector3 CrossProduct(Vector3& vec) const; public: float x,y,z; }; //标量乘向量 Vector3 operator*(float scalar, Vector3& vec);
//Vector3.cpp #include "Vector3.h" #include <cmath> Vector3::Vector3():x(0.0),y(0.0),z(0.0) { } Vector3::Vector3(float X,float Y,float Z):x(X),y(Y),z(Z) { } void Vector3::Zero() { x = y = z = 0; } Vector3 Vector3::operator-() const { return Vector3(-x,-y,-z); } float Vector3::Length() const { return sqrt(x*x+y*y+z*z); } Vector3 Vector3::operator*(float scalar) { return Vector3(this->x * scalar, this->y * scalar, this->z * scalar); } Vector3& Vector3::operator*=(float scalar) { return *this = *this * scalar; } Vector3& Vector3::operator/=(float scalar) { return *this = *this / scalar; } Vector3 operator*(float scalar, Vector3& vec) { return vec*scalar; } Vector3 Vector3::operator/(float scalar) { float temp = 1/ scalar; return *this * temp; } void Vector3::Normal() { //计算机计算乘法的速度比除法快 float temp = 1 / Length(); x *= temp; y *= temp; z *= temp; } Vector3 Vector3::operator+(Vector3& rhs) const { return Vector3(x+rhs.x,y+rhs.y,z+rhs.z); } Vector3& Vector3::operator+=(Vector3& rhs) { *this = *this + rhs; return *this; } Vector3 Vector3::operator-(Vector3& rhs) const { return Vector3(x-rhs.x,y-rhs.y,z-rhs.z); } Vector3& Vector3::operator-=(Vector3& rhs) { *this = *this - rhs; return *this; } float Vector3::Distance(Vector3& vec) const { return (*this - vec).Length(); } float Vector3::operator*(Vector3& rhs) const { return this->x * rhs.x + this->y * rhs.y + this->z * rhs.z; } Vector3 Vector3::CrossProduct(Vector3& vec) const { return Vector3(this->y * vec.z - this->z * vec.y, this->z * vec.x - this->x * vec.z, this->x * vec.y - this->y * vec.x); }
//main.cpp #include "Vector3.h" #include <iostream> using namespace std; void prfloatVec(Vector3 &vec) { cout << "[" << vec.x << "," << vec.y << "," << vec.z << "]" << endl; } int main() { cout << "hello vector" << endl; //测试构造函数 Vector3 v1(10,20,30); prfloatVec(v1); //测试默认拷贝构造函数 Vector3 v2(v1); prfloatVec(v2); //测试负向量 Vector3 v3 = -v1; prfloatVec(v3); //测试零向量 v2.Zero(); prfloatVec(v2); //测试计算向量长度 Vector3 v4(5,-4,7); float r = v4.Length(); cout << r << endl; //测试向量乘以标量 Vector3 v5(-5,0,0.4f); Vector3 v6 = v5 * -3; prfloatVec(v6); //测试向量乘等于标量 v5 *= -3; prfloatVec(v5); //测试向量除以标量 Vector3 v7(4.7f,-6,8); Vector3 v8 = v7 / 2; prfloatVec(v8); //测试标量乘以向量 Vector3 v9(1,2,3); Vector3 v10 = 2 * v9; prfloatVec(v10); //测试向量标准化 Vector3 v11(12,-5,0); v11.Normal(); prfloatVec(v11); //测试向量相加 Vector3 a(1,2,3); Vector3 b(4,5,6); Vector3 r1 = a + b; prfloatVec(r1); //测试向量相减 Vector3 r2 = b - a; prfloatVec(r2); //测试向量间距离 Vector3 x(5,0,0); Vector3 y(-1,8,0); float d = x.Distance(y); cout << d << endl; //向量相乘 Vector3 h1(3,-2,7); Vector3 h2(0,4,-1); float dp = h1 * h2; cout << dp << endl; //两向量间的角度 float arc = static_cast<float>(acos(dp/(h1.Length()*h2.Length())) * 180 / 3.14149); cout << arc << endl; //两向量叉乘 Vector3 t1(1,3,4); Vector3 t2(2,-5,8); Vector3 cp = t1.CrossProduct(t2); prfloatVec(cp); system("pause"); return 0; }
程序运行结果如下:
hello vector
[10,20,30]
[10,20,30]
[-10,-20,-30]
[0,0,0]
9.48683
[15,-0,-1.2]
[15,-0,-1.2]
[2.35,-3,4]
[2,4,6]
[0.923077,-0.384615,0]
[5,7,9]
[3,3,3]
10
-15
117.522
[44,0,-11]
相关文章推荐
- 如何粗略分析关键词的优化难度
- universal image loader在listview/gridview中滚动时重复加载图片的问题及解决方法
- android菜鸟学习笔记26----Android广播消息及BroadcastReceiver
- java基本控制语句的小例子
- 杭电1145 so you want to be a 2n-aire?
- zynq虐我千百遍——第4篇 Linaro之rootfs
- java io流常用类的使用
- ESP8266学习笔记5:ESP8266接入yeelink
- codeforces 558E A Simple Task 线段树
- c++ uniform_int_distribution 类
- thinkphp获取数组大小
- LeetCode#234 Palindrome Linked List
- 【读书笔记】ARC-环境下如何查看引用计数的变化
- web服务器并发访问如何提升
- Uva11825 - Hackers' Crackdown
- 嵌入式公司常考的一道指针题目:直接给内存地址赋值
- 我希望早几年知道的 5 个 Unix 命令
- Redis与Memcached的区别
- 不同数据类型与Json之间的转换
- LeetCode 4 Median of Two Sorted Arrays