Vector类的设计与实现_艾孜尔江撰

设计(头文件)

#pragma once

#include <iostream>

namespace RenderEngine {

	class Vector2
	{
	public:
		Vector2() : m_x(0), m_y(0) {};
		Vector2(const Vector2& vecToBeCopied) {
			this->setX(vecToBeCopied.getX());
			this->setY(vecToBeCopied.getY());
		};
		Vector2(float param) : m_x(param), m_y(param) {};
		Vector2(const float& a0, const float& a1) :
			m_x(a0), m_y(a1) {};
		~Vector2() {};
		void operator =(const Vector2& right);
		Vector2 operator +(const Vector2& right)const;
		Vector2 operator -(const Vector2& right)const;
		template<typename T>
		Vector2 operator *(const T& right) const;
		Vector2 operator /(const float& right) const;
		float operator *(const Vector2& right)const;
		bool operator ==(const float aNumbuer) {
			return (this->getX() == aNumbuer && this->getY() && aNumbuer);
		}
		bool operator ==(const Vector2& rightVec) {
			return (this->getX() == rightVec.getX() && this->getY() == rightVec.getY());
		}
		static void swap(Vector2& vecA, Vector2& vecB);

		float getX()const { return m_x; }
		float getY()const { return m_y; }
		void setX(const float& x) { m_x = x; }
		void setY(const float& y) { m_y = y; }
		float getLength();


	private:
		float m_x;
		float m_y;
	};

	class Vector3
	{
	public:
		Vector3() : m_x(0), m_y(0), m_z(0) {};
		Vector3(const Vector3& vecToBeCopied) {
			this->setX(vecToBeCopied.getX());
			this->setY(vecToBeCopied.getY());
			this->setZ(vecToBeCopied.getZ());
		};
		Vector3(float param) : m_x(param), m_y(param), m_z(param) {};
		Vector3(const float& a0, const float& a1, const float& a2) :
			m_x(a0), m_y(a1), m_z(a2) {};
		~Vector3() {};
		bool operator ==(float right)const;
		bool operator ==(const Vector3& right) const;
		Vector3 operator +(const Vector3& right)const;
		Vector3 operator -(const Vector3& right)const;
		Vector3 operator *(const float k)const;
		float operator *(const Vector3& right)const;
		template<typename T>
		Vector3 operator *(const T& right) const;
		Vector3 operator ^(const Vector3& right)const; // vector cross product
		void Normalize();
		static Vector3 Normalize(const Vector3& vecToBeNormalized);

		float getX()const { return m_x; }
		float getY()const { return m_y; }
		float getZ()const { return m_z; }
		float getR()const { return m_x; }
		float getG()const { return m_y; }
		float getB()const { return m_z; }
		void setX(const float& x) { m_x = x; }
		void setY(const float& y) { m_y = y; }
		void setZ(const float& z) { m_z = z; }
		void setR(const float& x) { m_x = x; }
		void setG(const float& y) { m_y = y; }
		void setB(const float& z) { m_z = z; }
		float getLength();


	private:
		float m_x;
		float m_y;
		float m_z;
	};

	class Vector4
	{
	public:
		Vector4() :
			m_x(0), m_y(0), m_z(0), m_w(0) {};
		Vector4(const Vector4& vecToBeCopied) {
			this->setX(vecToBeCopied.getX());
			this->setY(vecToBeCopied.getY());
			this->setZ(vecToBeCopied.getZ());
			this->setW(vecToBeCopied.getW());
		};
		Vector4(const Vector3& vecToBeCopied, bool isPoint = false) {
			this->setX(vecToBeCopied.getX());
			this->setY(vecToBeCopied.getY());
			this->setZ(vecToBeCopied.getZ());
			if (isPoint)this->setW(1);
			else this->setW(0);
		};
		Vector4(const float& a0, const float& a1, const float& a2, const float& a3 = 0) :
			m_x(a0), m_y(a1), m_z(a2), m_w(a3) {};
		~Vector4() {};
		bool operator ==(float right)const;
		bool operator ==(const Vector4& right)const;
		bool operator !=(const Vector4& right)const;
		Vector4 operator +(const Vector4& right)const;
		Vector4 operator -(const Vector4& right)const;
		Vector4 operator *(const float k)const;
		Vector4 operator /(const float k)const;
		float operator *(const Vector4& right)const;
		Vector4 operator ^(const Vector4& right)const; // vector cross product
		Vector4 getInterpolateVector(const Vector4& vecA, const Vector4& vecB, float factor);
		Vector4 getQuaternion(const Vector3 & lastPoint, const Vector3 & currentPoint);
		void Normalize();
		Vector4 GetNormalizedVector() const;
		static bool swap(Vector4& v1, Vector4& v2);

		float getX()const { return m_x; }
		float getY()const { return m_y; }
		float getZ()const { return m_z; }
		float getW()const { return m_w; }
		float getR()const { return m_x; }
		float getG()const { return m_y; }
		float getB()const { return m_z; }
		float getA()const { return m_w; }
		void setX(const float& x) { m_x = x; }
		void setY(const float& y) { m_y = y; }
		void setZ(const float& z) { m_z = z; }
		void setW(const float& w) { m_w = w; }
		void setR(const float& r) { m_x = r; }
		void setG(const float& g) { m_y = g; }
		void setB(const float& b) { m_z = b; }
		void setA(const float& a) { m_w = a; }

	private:
		float m_x;
		float m_y;
		float m_z;
		float m_w;
	};


	inline std::ostream& operator <<(std::ostream& os, const Vector4& vec4) { os << "x: " << vec4.getX() << "; y: " << vec4.getY() << "; z: " << vec4.getZ() << "; w: " << vec4.getW() << ". "; return os; }
	inline std::ostream& operator <<(std::ostream& os, const Vector3& vec3) { os << "x: " << vec3.getX() << "; y: " << vec3.getY() << "; z: " << vec3.getZ() << ". "; return os; }
	inline std::ostream& operator <<(std::ostream& os, const Vector2& vec2) { os << "x: " << vec2.getX() << "; y: " << vec2.getY() << ". "; return os; }
}



实现(C++文件)

#include <math.h>
#include "Vector.h"
#include "Math.h"

namespace RenderEngine {

	/************************************************************************/
	/* Vector2                                                              */
	/************************************************************************/

	void Vector2::operator=(const Vector2 & right)
	{
		this->setX(right.getX());
		this->setY(right.getY());
	}

	Vector2 Vector2::operator+(const Vector2& right) const
	{
		Vector2 result(this->getX() + right.getX(), this->getY() + right.getY());
		return result;
	}

	Vector2 Vector2::operator-(const Vector2& right) const
	{
		Vector2 result(this->getX() - right.getX(), this->getY() - right.getY());
		return result;
	}

	template<typename T>
	Vector2 Vector2::operator*(const T& k) const
	{
		Vector2 result(this->getX() * k, this->getY() * k);
		return result;
	}

	Vector2 Vector2::operator /(const float& k) const
	{
		if (k == 0.f || abs(k - 0.f) < EPSILON) {
			return Vector2();
		}
		float reciprocalK = 1 / k;
		Vector2 result(this->getX()*reciprocalK, this->getY()*reciprocalK);
		return result;
	}

	float Vector2::operator*(const Vector2& right) const
	{
		return (this->getX() * right.getX() + this->getY() * right.getY());
	}

	void Vector2::swap(Vector2 & vecA, Vector2 & vecB)
	{
		if (vecA == vecB)return;
		Vector2 tmp(vecA.getX(), vecA.getY());
		vecA = vecB;
		vecB = tmp;
	}

	float Vector2::getLength()
	{
		return sqrtf(powf(this->getX(), 2) + powf(this->getY(), 2));
	}



	/************************************************************************/
	/* Vector3                                                              */
	/************************************************************************/


	bool Vector3::operator==(const float right) const
	{
		bool xIsEqual = fabsf(this->getX() - right) <= EPSILON;
		bool yIsEqual = fabsf(this->getY() - right) <= EPSILON;
		bool zIsEqual = fabsf(this->getZ() - right) <= EPSILON;
		return (xIsEqual && yIsEqual && zIsEqual);
	}

	bool Vector3::operator==(const Vector3 & right) const
	{
		bool xIsEqual = fabsf(this->getX() - right.getX()) <= EPSILON;
		bool yIsEqual = fabsf(this->getY() - right.getY()) <= EPSILON;
		bool zIsEqual = fabsf(this->getZ() - right.getZ()) <= EPSILON;
		return (xIsEqual && yIsEqual && zIsEqual);
	}

	Vector3 Vector3::operator+(const Vector3 & right) const
	{
		Vector3 result(this->getX() + right.getX(), this->getY() + right.getY(), this->getZ() + right.getZ());
		return result;
	}

	Vector3 Vector3::operator-(const Vector3 & right) const
	{
		Vector3 result(this->getX() - right.getX(), this->getY() - right.getY(), this->getZ() - right.getZ());
		return result;
	}

	Vector3 Vector3::operator*(const float k) const
	{
		Vector3 result(this->getX() * k, this->getY() * k, this->getZ() * k);
		return result;
	}


	float Vector3::operator*(const Vector3 & right) const
	{
		return (this->getX()*right.getX() + this->getY()*right.getY() + this->getZ()*right.getZ());
	}

	template<typename T>
	Vector3 Vector3::operator*(const T& right) const
	{
		Vector3 result(
			this->getX()*right.matrix[0][0] + this->getY()*right.matrix[0][1] + this->getZ() * right.matrix[0][2],
			this->getY()*right.matrix[1][0] + this->getY()*right.matrix[1][1] + this->getZ() * right.matrix[1][2],
			this->getZ()*right.matrix[2][0] + this->getY()*right.matrix[2][1] + this->getZ() * right.matrix[2][2]);
		return result;
	}

	Vector3 Vector3::operator^(const Vector3 & right) const
	{
		Vector3 result;
		result.setX(this->getY() * right.getZ() - this->getZ() * right.getY());
		result.setY(this->getZ() * right.getX() - this->getX() * right.getZ());
		result.setZ(this->getX() * right.getY() - this->getY() * right.getX());
		return result;
	}

	void Vector3::Normalize()
	{
		float length = sqrtf(powf(this->getX(), 2) + powf(this->getY(), 2) + powf(this->getZ(), 2));
		this->setX(this->getX() / length);
		this->setY(this->getY() / length);
		this->setZ(this->getZ() / length);
	}

	Vector3 Vector3::Normalize(const Vector3& vecToBeNormalized)
	{
		Vector3 result;
		float length = sqrtf(powf(vecToBeNormalized.getX(), 2) + powf(vecToBeNormalized.getY(), 2) + powf(vecToBeNormalized.getZ(), 2));
		result.setX(vecToBeNormalized.getX() / length);
		result.setY(vecToBeNormalized.getY() / length);
		result.setZ(vecToBeNormalized.getZ() / length);
		return result;
	}

	float Vector3::getLength()
	{
		return sqrtf(powf(this->getX(), 2) + powf(this->getY(), 2) + powf(this->getZ(), 2));
	}




	/************************************************************************/
	/* Vector4                                                              */
	/************************************************************************/

	bool Vector4::operator==(float right) const
	{
		bool xIsEqual = fabsf(this->getX() - right) <= EPSILON;
		bool yIsEqual = fabsf(this->getY() - right) <= EPSILON;
		bool zIsEqual = fabsf(this->getZ() - right) <= EPSILON;
		bool wIsEqual = fabsf(this->getW() - right) <= EPSILON;
		return (xIsEqual && yIsEqual && zIsEqual && wIsEqual);
	}

	bool Vector4::operator==(const Vector4 & right) const
	{
		bool xIsEqual = fabsf(this->getX() - right.getX()) <= EPSILON;
		bool yIsEqual = fabsf(this->getY() - right.getY()) <= EPSILON;
		bool zIsEqual = fabsf(this->getZ() - right.getZ()) <= EPSILON;
		bool wIsEqual = fabsf(this->getW() - right.getW()) <= EPSILON;
		return (xIsEqual && yIsEqual && zIsEqual && wIsEqual);
	}

	bool Vector4::operator!=(const Vector4 & right) const
	{
		bool xIsInequal = fabsf(this->getX() - right.getX()) > EPSILON;
		bool yIsInequal = fabsf(this->getY() - right.getY()) > EPSILON;
		bool zIsInequal = fabsf(this->getZ() - right.getZ()) > EPSILON;
		bool wIsInequal = fabsf(this->getW() - right.getW()) > EPSILON;
		return (xIsInequal || yIsInequal || zIsInequal || wIsInequal);
	}

	Vector4 Vector4::operator +(const Vector4 & right) const
	{
		Vector4 result(this->getX() + right.getX(), this->getY() + right.getY(), this->getZ() + right.getZ(), this->getW() + right.getW());
		return result;
	}

	Vector4 Vector4::operator-(const Vector4 & right) const
	{
		Vector4 result(this->getX() - right.getX(), this->getY() - right.getY(), this->getZ() - right.getZ(), this->getW() - right.getW());
		return result;
	}

	Vector4 Vector4::operator*(const float k) const
	{
		Vector4 result(this->getX()*k, this->getY()*k, this->getZ() *k, this->getW() *k);
		return result;
	}

	Vector4 Vector4::operator/(const float k) const
	{
		float reciprocalK = 1 / k;
		Vector4 result(this->getX()*reciprocalK, this->getY()*reciprocalK, this->getZ() *reciprocalK, this->getW() *reciprocalK);
		return result;
	}

	float Vector4::operator *(const Vector4 & right) const
	{
		return this->getX()*right.getX() + this->getY()*right.getY() + this->getZ()*right.getZ() + this->getW()*right.getW();
	}

	Vector4 Vector4::operator ^(const Vector4& right) const
	{
		Vector4 result(this->getY()*right.getZ() - this->getZ()*right.getY(),
			this->getZ()*right.getX() - this->getX()*right.getZ(),
			this->getX()* right.getY() - this->getY()*right.getX());

		return result;
	}

	Vector4 Vector4::getInterpolateVector(const Vector4 & vecA, const Vector4 & vecB, float factor)
	{
		Vector4 result(
			LinearInerpolate(vecA.getX(), vecB.getX(), factor),
			LinearInerpolate(vecA.getY(), vecB.getY(), factor),
			LinearInerpolate(vecA.getZ(), vecB.getZ(), factor),
			1.f
		);
		return result;
	}

	Vector4 Vector4::getQuaternion(const Vector3 & lastPoint, const Vector3 & currentPoint)
	{
		Vector4 result;

		Vector3 perp = lastPoint ^ currentPoint;
		if (perp.getLength() > EPSILON)
		{
			result.setX(perp.getX());
			result.setY(perp.getY());
			result.setZ(perp.getZ());
			// w=cos(rotationAngle/2) ---> formula
			result.setW(lastPoint * currentPoint);
		}
		else
		{
			result.setX(.0f);
			result.setY(.0f);
			result.setZ(.0f);
			result.setW(.0f);
		}

		return result;
	}

	void Vector4::Normalize()
	{
		float length = sqrtf(powf(this->getX(), 2) + powf(this->getY(), 2) + powf(this->getZ(), 2));
		this->setX(this->getX() / length);
		this->setY(this->getY() / length);
		this->setZ(this->getZ() / length);
	}

	Vector4 Vector4::GetNormalizedVector() const 
	{
		Vector4 result;
		float length = sqrtf(powf(this->getX(), 2) + powf(this->getY(), 2) + powf(this->getZ(), 2));
		result.setX(this->getX() / length);
		result.setY(this->getY() / length);
		result.setZ(this->getZ() / length);
		return result;
	}

	bool Vector4::swap(Vector4 & v1, Vector4 & v2)
	{
		if (v1 != v2)
		{
			std::swap(v1.m_x, v2.m_x);
			std::swap(v1.m_y, v2.m_y);
			std::swap(v1.m_z, v2.m_z);
			std::swap(v1.m_w, v2.m_w);
		}
		return true;
	}
}





作者:艾孜尔江·艾尔斯兰
上一篇:类与对象之组合


下一篇:Flutter GetX使用---简洁的魅力!,阿里技术专家深入讲解