⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vector3.h

📁 Tixys source code, include G.711, G.726, IMA-ADPCM etc.
💻 H
字号:
/**
@file

@brief 3D vector maths using fixed-point arithmatic

For latest source code see http://www.tixy.clara.net/source/

Copyright (C) 2005 J.D.Medhurst (a.k.a. Tixy)

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifndef __VECTOR_H__
#define __VECTOR_H__

/**
@defgroup vector3 Maths - 3D Vectors

@brief Routines for handling 3 dimensional points, vectors and matrices.

This code is targeted at CPUs without hardware support for division or floating point.
It has been optimised for ARM CPUs but should be suitable for other RISC architecures.
@{
*/

#include "fix.h"



/**
@brief A class representing a 3vector

The three components of the vector; X,Y and Z, are 32bit fixed point numbers
with the binary point between bits 15 and 16.

@see fix
	 Fix

@version 2005-03-02
	Made Normal() faster by using integer multiplication to calculate cross product, as
	opposed to using fixed-point multiplication.

@version 2005-03-01
	Modified Normal() so that it copes with vectors of any magnitude - by scaling the
	vectors prior to cross product calculation.

*/
class Vector3
	{
public:
	/**
	Constructor which doesn't initialise the vector object.
	*/
	inline Vector3()
		{}

	/**
	Constructor which initialises the vector object.

	@param x Value for the X component.
	@param y Value for the Y component.
	@param z Value for the Z component.
	*/
	inline Vector3(fix x,fix y,fix z)
		: X(x), Y(y), Z(z) {}

	/**
	Uninary minus operator.

	@return A vector with component values of the same magnitude as this one,
			but with the signs of each value reversed.
	*/
	IMPORT Vector3 operator - () const;

	/**
	Calculate the sum of this vector and another.
	The resulting vector is the sum of the individual component values.
	If any component value overflows the range of 32bit fixed point numbers,
	then the result is undefined.

	@param vector The vector to add to this.

	@return The sum of this and \a vector.
	*/
	IMPORT Vector3 operator + (const Vector3& vector) const;

	/**
	Calculate the difference between this vector and another.
	The resulting vector is the difference between the individual component values.
	If any component value overflows the range of 32bit fixed point numbers,
	then the result is undefined.

	@param vector The vector to subtract from this.

	@return The difference between this and \a vector.
	*/
	IMPORT Vector3 operator - (const Vector3& vector) const;

	/**
	Scalar multiply.
	The resulting vector is the product of the individual component values
	of this vector multiplied by the given scalar value.
	If any component value overflows the range of 32bit fixed point numbers,
	then the result is undefined.

	@param scalar The scalar value to multiply by.
	
	@return The product of this vector and \a scalar.
	*/
	IMPORT Vector3 operator * (fix scalar) const;

	/**
	Scalar division.
	The resulting vector is the result of dividing the individual component values
	of this vector by the given scalar value.
	If any component value overflows the range of 32bit fixed point numbers,
	then the result is undefined.

	@param scalar The scalar value to divide by.

	@return The result of dividing this vector by \a scalar.
	*/
	IMPORT Vector3 operator / (fix scalar) const;

	/**
	Add a vector to this one.
	The result is the sum of the individual component values.
	If any component value overflows the range of 32bit fixed point numbers,
	then the result is undefined.

	@param vector The vector to add to this.
	
	@return A reference to this.

	@post This vector is set to the calculated sum.
	*/
	IMPORT Vector3& operator += (const Vector3& vector);

	/**
	Subract a vector from this one.
	The result is the difference between the individual component values.
	If any component value overflows the range of 32bit fixed point numbers,
	then the result is undefined.
	
	@param vector The vector to subtract from this.

	@return A reference to this.

	@post This vector is set to the calculated difference.
	*/
	IMPORT Vector3& operator -= (const Vector3& vector);

	/**
	Scalar multiply of this vector.
	Multiply each component of this vector by a scalar value.
	If any component value overflows the range of 32bit fixed point numbers,
	then the result is undefined.

	@param scalar The scalar value to multiply by.

	@return A reference to this.

	@post This vector is result of the scalar multiply.
	*/
	IMPORT Vector3& operator *= (fix scalar);

	/**
	Scalar divide of this vector.
	Divide each component of this vector by a scalar value.
	If any component value overflows the range of 32bit fixed point numbers,
	then the result is undefined.

	@param scalar The scalar value to divide by.

	@return A reference to this.

	@post This vector is result of the scalar division.
	*/
	IMPORT Vector3& operator /= (fix scalar);

	/**
	Equality operator.

	@param vector The vector to test equality with.

	@return True, if the individual components of this vector are the same their counterparts
			in \a vector. False, otherwise.
	*/
	IMPORT bool operator == (const Vector3& vector) const;

	/**
	Inequality operator.

	@param vector The vector to test equality with.

	@return True, if any of individual components of this vector differ from their counterparts
			in \a vector. False, otherwise.
	*/
	inline bool operator != (const Vector3& vector) const
		{ return !(*this==vector); }

	/**
	Calculate the dot product of this vector and a second vector.

	If any product of two components is greater than 0x2aaa.aaaa then the result
	is undefined.  This limitation can be met if all components, in both vectors,
	have a magnitude less than 104. (0x68.00000)

	@param vector The second vector.

	@return The dot product of this and \a vector.
	*/
	IMPORT fix DotProduct(const Vector3& vector) const;

	/**
	Calculate the cross product of this vector and a second vector.

	If any product of two components is greater than 0x4000.0000 then the result
	is undefined.  This limitation can be met if all components, in both vectors,
	have a magnitude less than 128. (0x80.00000)

	@param vector The second vector.

	@return The cross product of this and \a vector
	*/
	IMPORT Vector3 CrossProduct(const Vector3& vector) const;

	/**
	Calculate the length (magnitude) of this vector.
	Accuracy is limited to 24 significant bits.

	@return The length.
	*/
	IMPORT ufix Length() const;

	/**
	Compare the length (magnitude) of this vector with a given value.
	This is faster than comparing the value returned by Length(). E.g. instead of
	@code
	if(vector.Length()<distance)
	@endcode
	use
	@code
	if(vector.CompareLength(distance)<0)
	@endcode

	@param length The length value to compare with.

	@return 0, if the length of this vector is equal to \a length. <BR>
			1, if the length of this vector is greater than \a length. <BR>
			-1, if the length of this vector is less than \a length.
	*/
	IMPORT int CompareLength(ufix length) const;

	/**
	Compare the length of this vector with another.
	This is faster than comparing two values returned by Length(). E.g. instead of
	@code
	if(vector1.Length()<vector2.Length())
	@endcode
	use
	@code
	if(vector1.CompareLengths(vector2)<0)
	@endcode

	@param vector The vector to compare with.

	@return 0, if the lengths are the same. <BR>
			1, if the length of this is greater than the length of \a vector. <BR>
			-1, if the length of this is less than the length of \a vector.
	*/
	IMPORT int CompareLengths(const Vector3& vector) const;

	/**
	Calculate the square of the length of this vector.
	This is faster than Length() and is useful when comparing a vector length
	with a constant or pre-calculated value. (Comparing the square of lengths
	will give the same result as comparing the lengths.)

	@param fraction Set to the fraction part of the result, i.e the 32 bits to the
					right of the binary point.

	@return The integer part of the result.
	*/
	IMPORT uint32 LengthSquared(uint32& fraction) const;

	/**
	Calculate the unit vector which lies in the same direction as this vector.
	I.e. scale this vector so it has a length of 1.0.

	Rounding inacuracies mean the length of this 'unit' vector will actualy lie
	in the range 0x0.fffe to 0x1.0000.

	@return The unit vector. 
	*/
	IMPORT Vector3 UnitVector() const;

	/**
	Calculate the unit vector which is normal to this vector and a second vector.
	I.e. the unit vector which is at right angles to both this vector and the second vector;
	acording to the right-hand rule.

	Rounding inacuracies mean the length of this 'unit' vector will actualy lie
	in the range 0x0.fffe to 0x1.0000.

	@param vector The second vector.

	@return The unit vector normal to this and \a vector.
	*/
	IMPORT Vector3 Normal(const Vector3& vector) const;

	/**
	Calculate the angle between this vector and a second vector.

	@param vector The second vector.

	@return The angle between this and \a vector. This lies in the range 0x0000 and 0x8000.

	@see fixangle
	*/
	IMPORT fixangle Angle(const Vector3& vector) const;

	/**
	Calculate the unit vector which is normal to the two vectors formed by
	(\a point1 - this) and (\a point2 - this).
	I.e. the unit vector which is at right angles to both of these;
	acording to the right-hand rule.

	Rounding inacuracies mean the length of this 'unit' vector will actualy lie
	in the range 0x0.fffe to 0x1.0000.

	@param point1 The first point.
	@param point2 The second point.

	@return The normal vector.
	*/
	IMPORT Vector3 Normal(const Vector3& point1,const Vector3& point2) const;

	/**
	Calculate the angle between the two vectors formed by
	(\a point1 - this) and (\a point2 - this).

	@param point1 The first point.
	@param point2 The second point.

	@return The angle. This lies in the range 0x0000 and 0x8000.

	@see fixangle
	*/
	IMPORT fixangle Angle(const Vector3& point1,const Vector3& point2) const;

	/**
	Translate an array of vectors. I.e. add the given offset to each vector in an array.

	@param outVectors  Pointer to array where translated vectors will be written to.
	@param vectorCount Number of vectors in array.
	@param inVectors   Pointer to array vectors to be translated.
	@param offset	   The offset to add to each vector in the array.
	*/
	IMPORT static void Translate(Vector3* outVectors,uint vectorCount,const Vector3* inVectors,const Vector3& offset);

	/**
	Scale an array of vectors. I.e. perform a scalar multiply on each vector in an array.

	@param outVectors  Pointer to array where scaled vectors will be written to.
	@param vectorCount Number of vectors in array.
	@param inVectors   Pointer to array vectors to be scaled.
	@param scale	   The value to scale each component of each vector by.
	*/
	IMPORT static void Scale(Vector3* outVectors,uint vectorCount,const Vector3* inVectors,fix scale);

private:

	/**
	Scale the components of this array such that the component with the largest
	magnitude has its most-significant bit at the given position.

    @param bits Bit position for MSB of largest component.
	*/
	void NormaliseComponents(uint bits);

public:
	fix X; /**< The X component */
	fix Y; /**< The Y component */
	fix Z; /**< The Z component */
	};


/**
@brief A type representing a 3D point
*/
typedef Vector3 Point3;



/**
@brief A class representing a 3x3 matrix.
*/
class Matrix3
	{
public:
	/**
	Constructor which doesn't initialise the matrix object
	*/
	inline Matrix3()
		{}

	/**
	Constructor which initialises the matrix object using three 3vectors

	@param row1 Values for first row in matrix.
	@param row2 Values for second row in matrix.
	@param row3 Values for third row in matrix.
	*/
	inline Matrix3(const Vector3 row1,const Vector3 row2,const Vector3 row3)
		: Row1(row1), Row2(row2), Row3(row3) {}

	/**
	Multiply this matrix by a 3vector.

	@param vector The vector to multiply by. This is treated as a column vector.

	@return Result of mutiplying this matrix by \a vector
	*/
	IMPORT Vector3 operator * (const Vector3& vector) const;

	/**
	Transpose a matrix. (Exchange rows with columns.)

	@return The transposition of this matrix.
	*/
	IMPORT Matrix3 Transposition() const;

	/**
	Tranform an array of vectors by multiplying each against this matrix, acording
	to the operator*() function.

	@param outVectors  Pointer to array where transformed vectors will be written to.
	@param vectorCount Number of vectors in array.
	@param inVectors   Pointer to array vectors to be transformed.
	*/
	IMPORT void Transform(Vector3* outVectors,uint vectorCount,const Vector3* inVectors);
public:
	Vector3 Row1; /**< The elements for row 1 of the matrix */
	Vector3 Row2; /**< The elements for row 2 of the matrix */
	Vector3 Row3; /**< The elements for row 3 of the matrix */
};


/** @} */ // End of group

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -