学习笔记——关于向量

一、向量运算


点乘:a * b = |a| |b| cosα
投影
叉乘:|a X b| = |a| |b| sinα  向量计算: x =y1*z2 - z1*y2;    y = z1*x2 - x1*z2;    z = x1*y2 - y1*x2;
...

二、设计决策


  1. 这里用float类型。当今的处理器处理浮点数能在处理整数的周期内完成,并且还提供向量处理器来执行浮点向量运算,所以不用担心浮点类型的计算效率。
  2. 关于返回类型,一般来说,返回类型是一个引用会提高效率(因为少调用构造函数)。但是在一些情况下(如+等重载运算)则需要返回类实例,这里的处理是在return时直接构造,显式构造临时对象。但是这还是会造成性能下降(因为还是需要调用构造函数)。然而,我们似乎可以使用对象池以减少这种效率问题,但是除了轻微的性能提升,提高了巨大的代码复杂性。所以这里还是使用了return时直接构造。
  3. 在设计代码时,时刻牢记效率问题。保持类的精简,同时也不要为了轻微的性能优化付出很大的代码复杂性。

三、向量类

/***************************************************************
 *
 *	vector3类:简单的3D向量类
 *
****************************************************************/
#include <math.h>

class Vector3 {
public:
	float x, y, z;
/**************构造函数****************************/
	//默认初始化函数
	Vector3(){}
	/****与构造函数体内赋值不一样 赋值是先调用无参构造,再调用赋值 初始化是直接调用带参构造***/
	//构造函数初始化表 传入为一个Vector3实例
	Vector3(const Vector3 &v) : x(v.x), y(v.y), z(v.z) {}
	//构造函数 传入为三个分量
	Vector3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}

/***************标准对象操作***********************/
	//赋值重载 返回引用
	Vector3 &operator = (const Vector3 &v) {
		x = v.x; y = v.y; z = v.z;
		return *this;
	}
	/****(这里的const表明此函数不会对数据成员进行更改)*/
	//重载比较算符
	bool operator ==(const Vector3 &v) const {
		return x==v.x && y==v.y && z==v.z;
	}
	bool operator !=(const Vector3 &v) const {
		return x!=v.x || y!=v.y || z!=v.z;
	}
/***************向量运算***************************/
	//置为零向量
	void zero() { x = y = z = 0.0f; }
	//重载 取负 运算符
	Vector3 operator - () const { return Vector3(-x,-y,-z); }
	//重载 +,- 运算符
	Vector3 operator + (const Vector3 &v) const {
		return Vector3(x + v.x, y + v.y, z + v.z);
	}
	Vector3 operator - (const Vector3 &v) const {
		return Vector3(x - v.x, y - v.y, z - v.z);
	}
	//与标量的乘、除法
	Vector3 operator *(float k) const {
		return Vector3(x*k, y*k, z*k);
	}
	Vector3 operator /(float k) const {
		float oneOverK = 1.0f / k;		//这里不对零进行检查
		return Vector3(x*oneOverK, y*oneOverK, z*oneOverK);
	}
	//自运算 算符
	Vector3 &operator +=(const Vector3 &v) {
		x += v.x; y += v.y; z += v.z;
		return *this;
	}
	Vector3 &operator -=(const Vector3 &v) {
		x -= v.x; y -= v.y; z -= v.z;
		return *this;
	}
	Vector3 &operator *=(float k) {
		x *= k; y *= k; z *= k;
		return *this;
	}
	Vector3 operator /=(float k) {
		float oneOverK = 1.0f / k;		//这里不对零进行检查
		x *= oneOverK; y *= oneOverK; z *= oneOverK;
		return *this;
	}
	//向量标准化
	void normalize() {
		float magSq = x*x + y*y + z*z;
		if (magSq > 0.0f) { //检查除零
			float oneOverMag = 1.0 / sqrt(magSq);
			x *= oneOverMag;
			y *= oneOverMag;
			z *= oneOverMag;
		}
	}
	//向量点乘
	float operator *(const Vector3 &v) const {
		return x*v.x + y*v.y + z*v.z;
	}
};

/***************************************************************
 *
 *	非成员函数
 *
****************************************************************/
//向量求模
inline float vectorMag(const Vector3 &v) {
	return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
}
//计算向量叉乘
inline Vector3 crossProduct(const Vector3 &v1, const Vector3 &v2) {
	return Vector3(
		v1.y*v2.z - v1.z*v2.y,
		v1.z*v2.x - v1.x*v2.z,
		v1.x*v2.y - v1.y*v2.x
		);
}
//实现标量左乘
inline Vector3 operator *(float k, const Vector3 &v) {
	return Vector3(k*v.x, k*v.y, k*v.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);
}

/***************************************************************
 *
 *	全局变量
 *
****************************************************************/
//全局零向量
extern const Vector3 zeroVector;


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值