向量与坐标系

1.1 向量与坐标系

1.1.1 向量与坐标系的应用

零向量: 零向量是没有方向的向量;

负向量: 负向量是与原向量方向相反、长度相等的向量;

向量的模: 即向量的长度,向量中各标量的平方和开根可以得到向量的模;

请添加图片描述

/*
* 三维坐标取模
*/
float mod(const Vector3& pos)
{
	if (*this == VEC3_ZERO)
			return 0;
	float squaresSum = x * x + y * y + z * z;
	return sqrt(squaresSum);
}

单位向量: 长度为1的向量,向量除以向量的模等于该向量的单位向量;

请添加图片描述

/*
* 归一化,获取单位向量
*/
Vector3 normal() const 
{ 
	float tep = mod();
	if (tep == 0)
		return VEC3_ZERO;
	return *this/tep;
}

坐标间的距离: 将两个坐标相减所得到的新坐标进行取模就能得到坐标间的距离;

/*
* 计算与指定坐标的距离
*/
float distance(const Vector3& vec) {
	Vector3 tep = *this - vec;
	float distance = tep.mod();
	return distance;
}
/*
* 计算两个坐标间的距离
*/
inline float Distance(const Vector3& vec1, const Vector3& vec2) {
	Vector3 tep = vec1 - vec2;
	float distance = tep.mod();
	return distance;
}

向量点乘: 向量点乘的结果是一个标量,公式如下;
在这里插入图片描述
在这里插入图片描述

利用向量点乘可以获得两个向量的方向:点乘结果等于 0 两个向量垂直,大于 0 方向相同,小于 0 方向相反;

利用向量点乘还可以获得夹角:

a * b = || a || || b || cosθ => cosθ = (a * b) / (|| a || || b || ) => θ = arccos((a * b) / (|| a || || b || ))

/*
* 点乘
*/
inline float Dot(const Vector3& vec1, const Vector3& vec2) {
	float result = vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
	return result;
}
/*
* 计算与指定坐标的夹角
*/
float angle(const Vector3& vec) const{
	float dot = Dot(*this, vec);
	float mod1 = mod();
	float mod2 = vec.mod();
	if (mod1 == 0.0f || mod2 == 0.0f)
		return 0.0f;
	float result = acosf(dot / (mod1 + mod2));
	return result;
}
/*
* 获取两个向量间的夹角
*/
inline float Angle(const Vector3& vec1, const Vector3& vec2) {
	float dot = Dot(vec1, vec2);
	float mod1 = vec1.mod();
	float mod2 = vec2.mod();
	if (mod1 == 0.0f || mod2 == 0.0f)
		return 0.0f;
	float angle = acosf(dot / (mod1 + mod2));
	return angle;
}

向量叉乘: 向量叉乘的结果是一个向量,叉乘的结果垂直于进行叉乘的两个向量,公式如下;
在这里插入图片描述
在这里插入图片描述

叉乘获得的结果进行模运算的结果是进行叉乘前的两个向量所映射出的平行四边形的面积;

叉乘还可用来判断两个向量是否平行,如果叉乘结果是零向量则两个向量是平行的;

/*
* 叉乘
*/
inline Vector3 Cross(const Vector3& vec1, const Vector3& vec2) {
	return Vector3(
		vec1.y * vec2.z - vec1.z * vec2.y,
		vec1.z * vec2.x - vec1.x * vec2.z,
		vec1.x * vec2.y - vec1.y * vec2.x
	);
}
/*
* 两个向量的方向是否平行
*/
inline bool IsParallel(const Vector3& vec1, const Vector3& vec2) {
	Vector3 result = Cross(vec1, vec2);
	return result == VEC3_ZERO;
}
/*
* 计算与指定坐标的方向是否平行
*/
bool isParallel(const Vector3& vec) {
	Vector3 result = Cross(*this, vec);
	return result == VEC3_ZERO;
}

1.1.2 完整测试代码

#include <cmath>
#include <sstream>

const Vector3 VEC3_ZERO = Vector3(0, 0, 0);
const Vector3 VEC3_ONE = Vector3(1, 1, 1);
class Vector3
{
public:
	float x, y, z;
	Vector3() {}
	Vector3(const Vector3& pos) : x(pos.x), y(pos.y), z(pos.z) {}
	Vector3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {}
	Vector3 operator +() const { 
        return Vector3(fabs(x), fabs(y), fabs(z)); 
    }
	Vector3 operator -() const { 
        return Vector3(-x, -y, -z); 
    }
	Vector3 operator +(Vector3 vec) const { 
        return Vector3(x + vec.x, y + vec.y, z + vec.z); 
    }
	Vector3 operator +=(Vector3 vec) {
		x += vec.x;
		y += vec.y;
		z += vec.z;
		return *this;
	}
	Vector3 operator -(Vector3 vec) const { 
        return Vector3(x - vec.x, y - vec.y, z - vec.z); 
    }
	Vector3 operator -=(Vector3 vec) {
		x -= vec.x;
		y -= vec.y;
		z -= vec.z;
		return *this;
	}
	Vector3 operator *(float num) const { 
        return Vector3(x * num, y * num, z * num); 
    }
	Vector3 operator *=(float num) {
		x *= num;
		y *= num;
		z *= num;
		return *this;
	}
	Vector3 operator /(float num) const { 
		float tep = 1.0f / num;
		const float threshold = 1e-6; 
		if (tep < threshold)
			return VEC3_ZERO;
		Vector3 result = Vector3(
			x * tep , 
			y * tep, 
			z * tep
		);
		return result;
	}
	Vector3 operator /=(float num) {
		float tep = 1.0f / num;
		float tep = 1.0f / num;
		const float threshold = 1e-6;
		if (tep < threshold) 
			*this = VEC3_ZERO;
		else
			*this *= tep;
		return *this;
	}
	bool operator ==(const Vector3 &vec) const{
		bool isbool = vec.x == x && vec.y == y && vec.z == z;
		return isbool;
	}
	/*
	* 坐标置0
	*/
	void zero() { x = y = z = 0.0f; }
	
	/*
	* 取向量模
	*/
	float mod() const
	{
		if (*this == VEC3_ZERO)
			return 0;
		float squaresSum = x * x + y * y + z * z;
		return sqrt(squaresSum);
	}
	/*
	* 归一化,获取单位向量
	*/
	Vector3 normal() const 
	{ 
		float tep = mod();
		if (tep == 0)
			return VEC3_ZERO;
		return *this/tep;
	}
	/*
	* 返回坐标字符串
	*/
	std::string string() const {
		std::stringstream ss;
		ss << "Vector3:" << "(" << x << ", " << y << ", " << z << ")";
		return ss.str();
	}
	/*
	* 计算与指定坐标的距离
	*/
	float distance(const Vector3& vec) const{
		Vector3 tep = *this - vec;
		float distance = tep.mod();
		return distance;
	}
	/*
	* 计算与指定坐标的夹角
	*/
	float angle(const Vector3& vec) const{
		float dot = Dot(*this, vec);
		float mod1 = mod();
		float mod2 = vec.mod();
		if (mod1 == 0.0f || mod2 == 0.0f)
			return 0.0f;
		float result = acosf(dot / (mod1 + mod2));
		return result;
	}
	/*
	* 计算与指定坐标的方向是否平行
	*/
	bool isParallel(const Vector3& vec) {
		Vector3 result = Cross(*this, vec);
		return result == VEC3_ZERO;
	}
};
inline Vector3 operator *(float num, const Vector3 &vec) {
	return vec * num;
}
/*
* 计算两个坐标间的距离
*/
inline float Distance(const Vector3& vec1, const Vector3& vec2) {
	Vector3 tep = vec1 - vec2;
	float distance = tep.mod();
	return distance;
}
/*
* 点乘
*/
inline float Dot(const Vector3& vec1, const Vector3& vec2) {
	float result = vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;
	return result;
}
/*
* 叉乘
*/
inline Vector3 Cross(const Vector3& vec1, const Vector3& vec2) {
	return Vector3(
		vec1.y * vec2.z - vec1.z * vec2.y,
		vec1.z * vec2.x - vec1.x * vec2.z,
		vec1.x * vec2.y - vec1.y * vec2.x
	);
}
/*
* 获取两个向量间的夹角
*/
inline float Angle(const Vector3& vec1, const Vector3& vec2) {
	float dot = Dot(vec1, vec2);
	float mod1 = vec1.mod();
	float mod2 = vec2.mod();
	if (mod1 == 0.0f || mod2 == 0.0f)
		return 0.0f;
	float angle = acosf(dot / (mod1 + mod2));
	return angle;
}
/*
* 两个向量的方向是否平行
*/
inline bool IsParallel(const Vector3& vec1, const Vector3& vec2) {
	Vector3 result = Cross(vec1, vec2);
	return result == VEC3_ZERO;
}
```\
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jc_caterpillar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值