左手坐标系的直观表示: ![LH.JPG](/images/cppblog_com/mybios/ArticlePics/LH.JPG) 向量的表示(轴对齐包围盒(AABB(axially aligned bounding box))): ![Vector.JPG](/images/cppblog_com/mybios/ArticlePics/Vector.JPG) 2D向量的长度: ||v|| = sqrt(vx*vx + vy*vy)3D向量的长度: ||v|| = sqrt(vx*vx + vy*vy + vz*vz)
标准化向量=此向量/此向量的长度=vx / ||v|| , vy / ||v|| , vz / ||v||
标准化后的向量的头接触到圆心在原点的单位圆(单位圆的半径为1)
向量加法的几何意义(三角形法则):
![vAdd.JPG](/images/cppblog_com/mybios/ArticlePics/vAdd.JPG)
计算一个点到另一个点的位移可以使用三角形法则和向量减法来解决这个问题:
![Vector1.JPG](/images/cppblog_com/mybios/ArticlePics/Vector1.JPG) 两点间距离的公式:设两点分别为3D向量a和b 则距离(a,b)=||b-a||=sqrt((bx - ax)2 +(by - ay)2 +(bz - az)2 )
向量点乘:点乘等于向量大小与向量夹角的cos值的积,其中c为两点a和b的夹角: a点乘b=||a||*||b||*cos(c)
计算向量的夹角:c =acos( (a*b)/(||a|| * ||b||))
如果a和b是单位向量,则c=acos(a*b)
当点乘结果大于0,则夹角小于90度 当点乘结果等于0,则夹角等于90度 当点乘结果小于0,则夹角大于90度
向量差乘:
![Vector2.JPG](/images/cppblog_com/mybios/ArticlePics/Vector2.JPG)
向量的封装类:
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**////////////////////////////////////////////////////////////////////////////// //
// 3D Math Primer for Games and Graphics Development
//
// Vector3.h - Declarations for 3D vector class
//
// Visit gamemath.com for the latest version of this file.
//
// For additional comments, see Chapter 6.
//
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//////////////////////////////////////////////////////////////////////////////![](/Images/OutliningIndicators/None.gif)
#ifndef __VECTOR3_H_INCLUDED__
#define __VECTOR3_H_INCLUDED__
![](/Images/OutliningIndicators/None.gif)
#include <math.h>
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**////////////////////////////////////////////////////////////////////////////// //
// class Vector3 - a simple 3D vector class
//
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//////////////////////////////////////////////////////////////////////////////![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) class Vector3 {
public:
![](/Images/OutliningIndicators/InBlock.gif)
// Public representation: Not many options here.
![](/Images/OutliningIndicators/InBlock.gif)
float x,y,z;
![](/Images/OutliningIndicators/InBlock.gif)
// Constructors
![](/Images/OutliningIndicators/InBlock.gif)
// Default constructor leaves vector in
// an indeterminate state
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3() {}
![](/Images/OutliningIndicators/InBlock.gif)
// Copy constructor
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3(const Vector3 &a) : x(a.x), y(a.y), z(a.z) {}
![](/Images/OutliningIndicators/InBlock.gif)
// Construct given three values
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {}
![](/Images/OutliningIndicators/InBlock.gif)
// Standard object maintenance
![](/Images/OutliningIndicators/InBlock.gif)
// Assignment. We adhere to C convention and
// return reference to the lvalue
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 &operator =(const Vector3 &a) {
x = a.x; y = a.y; z = a.z;
return *this;
}
![](/Images/OutliningIndicators/InBlock.gif)
// Check for equality
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) bool operator ==(const Vector3 &a) const {
return x==a.x && y==a.y && z==a.z;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) bool operator !=(const Vector3 &a) const {
return x!=a.x || y!=a.y || z!=a.z;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
// Vector operations
![](/Images/OutliningIndicators/InBlock.gif)
// Set the vector to zero
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) void zero() { x = y = z = 0.0f; }
![](/Images/OutliningIndicators/InBlock.gif)
// Unary minus returns the negative of the vector
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 operator -() const { return Vector3(-x,-y,-z); }
![](/Images/OutliningIndicators/InBlock.gif)
// Binary + and - add and subtract vectors
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 operator +(const Vector3 &a) const {
return Vector3(x + a.x, y + a.y, z + a.z);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 operator -(const Vector3 &a) const {
return Vector3(x - a.x, y - a.y, z - a.z);
}
![](/Images/OutliningIndicators/InBlock.gif)
// Multiplication and division by scalar
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 operator *(float a) const {
return Vector3(x*a, y*a, z*a);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 operator /(float a) const {
float oneOverA = 1.0f / a; // NOTE: no check for divide by zero here
return Vector3(x*oneOverA, y*oneOverA, z*oneOverA);
}
![](/Images/OutliningIndicators/InBlock.gif)
// Combined assignment operators to conform to
// C notation convention
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 &operator +=(const Vector3 &a) {
x += a.x; y += a.y; z += a.z;
return *this;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 &operator -=(const Vector3 &a) {
x -= a.x; y -= a.y; z -= a.z;
return *this;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 &operator *=(float a) {
x *= a; y *= a; z *= a;
return *this;
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) Vector3 &operator /=(float a) {
float oneOverA = 1.0f / a;
x *= oneOverA; y *= oneOverA; z *= oneOverA;
return *this;
}
![](/Images/OutliningIndicators/InBlock.gif)
// Normalize the vector
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) void normalize() {
float magSq = x*x + y*y + z*z;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if (magSq > 0.0f) { // check for divide-by-zero
float oneOverMag = 1.0f / sqrt(magSq);
x *= oneOverMag;
y *= oneOverMag;
z *= oneOverMag;
}
}
![](/Images/OutliningIndicators/InBlock.gif)
// Vector dot product. We overload the standard
// multiplication symbol to do this
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) float operator *(const Vector3 &a) const {
return x*a.x + y*a.y + z*a.z;
}
};
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**////////////////////////////////////////////////////////////////////////////// //
// Nonmember functions
//
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//////////////////////////////////////////////////////////////////////////////![](/Images/OutliningIndicators/None.gif)
// Compute the magnitude of a vector
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) inline float vectorMag(const Vector3 &a) {
return sqrt(a.x*a.x + a.y*a.y + a.z*a.z);
}
![](/Images/OutliningIndicators/None.gif)
// Compute the cross product of two vectors
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) inline Vector3 crossProduct(const Vector3 &a, const Vector3 &b) {
return Vector3(
a.y*b.z - a.z*b.y,
a.z*b.x - a.x*b.z,
a.x*b.y - a.y*b.x
);
}
![](/Images/OutliningIndicators/None.gif)
// Scalar on the left multiplication, for symmetry
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) inline Vector3 operator *(float k, const Vector3 &v) {
return Vector3(k*v.x, k*v.y, k*v.z);
}
![](/Images/OutliningIndicators/None.gif)
// Compute the distance between two points
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) 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);
}
![](/Images/OutliningIndicators/None.gif)
// Compute the distance between two points, squared. Often useful
// when comparing distances, since the square root is slow
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) inline float distanceSquared(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 dx*dx + dy*dy + dz*dz;
}
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**////////////////////////////////////////////////////////////////////////////// //
// Global variables
//
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**//////////////////////////////////////////////////////////////////////////////![](/Images/OutliningIndicators/None.gif)
// We provide a global zero vector constant
![](/Images/OutliningIndicators/None.gif)
extern const Vector3 kZeroVector;
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) /**////////////////////////////////////////////////////////////////////////////// #endif // #ifndef __VECTOR3_H_INCLUDED__
![](/Images/OutliningIndicators/None.gif)
|