CVector.cpp
上传用户:arsena_zhu
上传日期:2022-07-12
资源大小:399k
文件大小:11k
- /*
- Class Name:
- CVector.
- Created by:
- Allen Sherrod (Programming Ace of www.UltimateGameProgramming.com).
- Description:
- This class represents a 3D point for a vertex's x, y, z.
- */
- #include"main.h" // CVector class.
- //#define M_PI 3.141592654
- /*******************************************************************************
- * VECTOR
- *******************************************************************************/
- CVector::CVector()
- {
- // Initialize the variables to 0.
- x = y = z = 0.0;
- }
- CVector::CVector(float X, float Y, float Z)
- {
- // Initialize the varibles to the data in X, Y, and Z.
- x = X;
- y = Y;
- z = Z;
- }
- CVector::CVector(const CVector &v)
- {
- // Initialize this object to v.
- x = v.x;
- y = v.y;
- z = v.z;
- }
- void CVector::operator =(CVector v)
- {
- // Make this objects x, y, and z equal to the object on the right of the = sign.
- x = v.x;
- y = v.y;
- z = v.z;
- }
- void CVector::operator =(float f)
- {
- // Make this objects x, y, and z equal to the object on the right of the = sign.
- x = f;
- y = f;
- z = f;
- }
- CVector CVector::operator -(CVector v)
- {
- // Return the value of this vector - v.
- return CVector(x - v.x, y - v.y, z - v.z);
- }
- CVector CVector::operator +(CVector v)
- {
- // Return the value of this vector + v.
- return CVector(x + v.x, y + v.y, z + v.z);
- }
- CVector CVector::operator *(CVector v)
- {
- // Return the value of this vector * v.
- return CVector(x * v.x, y * v.y, z * v.z);
- }
- CVector CVector::operator /(CVector v)
- {
- // Return the value of this vector / v.
- return CVector(x / v.x, y / v.y, z / v.z);
- }
- CVector CVector::operator +(float f)
- {
- // Return the value of this vector + f.
- return CVector(x + f, y + f, z + f);
- }
- CVector CVector::operator -(float f)
- {
- // Return the value of this vector - f.
- return CVector(x - f, y - f, z - f);
- }
- CVector CVector::operator *(float f)
- {
- // Return the value of this vector * f.
- return CVector(x * f, y * f, z * f);
- }
- CVector CVector::operator /(float f)
- {
- // Return the value of this vector / f. We do this by multiplying the recip.
- f = 1/f;
- return CVector(x * f, y * f, z * f);
- }
- void CVector::operator +=(CVector v)
- {
- // Add this by object v and store results here.
- x += v.x;
- y += v.y;
- z += v.z;
- }
- void CVector::operator -=(CVector v)
- {
- // Subtract this by object v and store results here.
- x -= v.x;
- y -= v.y;
- z -= v.z;
- }
- void CVector::operator *=(CVector v)
- {
- // Mul this by object v and store results here.
- x *= v.x;
- y *= v.y;
- z *= v.z;
- }
- void CVector::operator /=(CVector v)
- {
- // Divide this by object v and store results here.
- x /= v.x;
- y /= v.y;
- z /= v.z;
- }
- void CVector::operator +=(float f)
- {
- // Add this by object f and store results here.
- x += f;
- y += f;
- z += f;
- }
- void CVector::operator -=(float f)
- {
- // Subract this by object f and store results here.
- x -= f;
- y -= f;
- z -= f;
- }
- void CVector::operator *=(float f)
- {
- // Multiply this by object f and store results here.
- x *= f;
- y *= f;
- z *= f;
- }
- void CVector::operator /=(float f)
- {
- // Divide this by object f and store results here by multiplying by the recip.
- f = 1/f;
- x *= f;
- y *= f;
- z *= f;
- }
- bool CVector::operator >(CVector v)
- {
- return (GetLength() > v.GetLength());
- }
- bool CVector::operator <(CVector v)
- {
- return (GetLength() < v.GetLength());
- }
- bool CVector::operator >(float f)
- {
- return (GetLength() > f);
- }
- bool CVector::operator <(float f)
- {
- return (GetLength() < f);
- }
- bool CVector::operator ==(CVector v)
- {
- // Return true if all equal each other, false if one or more don't.
- return ((x == v.x) && (y== v.y) && (z == v.z));
- }
- bool CVector::operator !=(CVector v)
- {
- // Return true if one or all don't equal each other, false if they equal.
- return !((x == v.x) && (y== v.y) && (z == v.z));
- }
- void CVector::CrossProduct(CVector v1, CVector v2)
- {
- // Get the cross product of v1 and v2 and store it in this vector.
- x = ((v1.y * v2.z) - (v1.z * v2.y));
- y = ((v1.z * v2.x) - (v1.x * v2.z));
- z = ((v1.x * v2.y) - (v1.y * v2.x));
- }
- void CVector::CrossProduct3(CVector v1, CVector v2, CVector v3)
- {
- // Get the cross product of v1, v2, and v3.
- x = v1.y * v2.z +
- v1.z * v3.y +
- v2.y * v3.z -
- v1.y * v3.z -
- v1.z * v2.y -
- v2.z * v3.y;
- y = v1.x * v3.z +
- v1.z * v2.x +
- v2.z * v3.x -
- v1.x * v2.z -
- v1.z * v3.x -
- v2.x * v3.z;
- z = v1.x * v2.y +
- v1.y * v3.x +
- v2.x * v3.y -
- v1.x * v3.y -
- v1.y * v2.x -
- v2.y * v3.x;
- }
- float CVector::DotProduct3(CVector v1)
- {
- // Get the dot product of v1 and this object and return it.
- return x * v1.x + y * v1.y + z * v1.z;
- }
- float CVector::GetLength()
- {
- // Return the length for this object.
- return (float)sqrt((x * x + y * y + z * z));
- }
- void CVector::Normal()
- {
- // Reduce this object to a unit vector.
- float length = GetLength();
- if(length == 0.0f)
- length = 1.0f;
- x = x/length;
- y = y/length;
- z = z/length;
- }
- CVector CVector::Normalized()
- {
- float length = GetLength();
- if(length == 0.0f) length = 1.0f;
- CVector result;
- result.x = x / length;
- result.y = y / length;
- result.z = z / length;
- return result;
- }
- void CVector::Normalize(CVector Triangle[])
- {
- // Normalize a triangle and store results in this object.
- CVector v1, v2;
- v1.x = Triangle[0].x - Triangle[1].x;
- v1.y = Triangle[0].y - Triangle[1].y;
- v1.z = Triangle[0].z - Triangle[1].z;
- v2.x = Triangle[1].x - Triangle[2].x;
- v2.y = Triangle[1].y - Triangle[2].y;
- v2.z = Triangle[1].z - Triangle[2].z;
- CrossProduct(v1, v2);
- Normal();
- }
- /*
- void CVector::CalculateTangentVector(CVector Point1, CVector Point2, CVector Point3,
- CVector NormalOfA, CTexCoord P1Tex, CTexCoord P2Tex,
- CTexCoord P3Tex)
- {
- // Get the vector between point 1 and point 2.
- CVector VectorAB = Point2 - Point1;
- // Get the vector between point 1 and point 3.
- CVector VectorAC = Point3 - Point1;
- // Compute the components of the vectors to the vertex normal of the first point.
- CVector ProjAB = VectorAB - (NormalOfA * NormalOfA.DotProduct3(VectorAB));
- CVector ProjAC = VectorAC - (NormalOfA * NormalOfA.DotProduct3(VectorAC));
- // Calculate the tu difference of point 2 and 1 then of point 3 and 1.
- float TexCoorUAB = P2Tex.tu - P1Tex.tu;
- float TexCoorUAC = P3Tex.tu - P1Tex.tu;
- // Calculate the tv difference of point 2 and 1 then of point 3 and 1.
- float TexCoorVAB = P2Tex.tv - P1Tex.tv;
- float TexCoorVAC = P3Tex.tv - P1Tex.tv;
- // Switch the sign if the u of point 1 and 3 * v of 1 and 2 is greater than u of 1 and 2 *
- // v of point 1 and 3.
- if((TexCoorUAC * TexCoorVAB) > (TexCoorUAB * TexCoorVAC))
- {
- TexCoorUAC = -TexCoorUAC;
- TexCoorUAB = -TexCoorUAB;
- }
- // Calculate the tangent vector, normalize it, then return it (the normal values).
- CVector Tangent = (ProjAB * TexCoorUAC) - (ProjAC * TexCoorUAB);
- Tangent.Normal();
- *this += Tangent;
- }
- */
- void CVector::ExtendVertexPos(CVector currentVertex, CVector lightPos, float Extend)
- {
- CVector lightDir; // Direction of the light to the vertex position.
- CVector newPos; // New extended vertex position to make up the shadow volume.
- // Get the light direction from the vertex position and the light position.
- lightDir = currentVertex - lightPos;
- // Now that we know where its going we add it to the position of the light so
- // we get the correct, new position. We multiply it by a passed it value to
- // give the volume some distance or things won't come out quite as we want.
- newPos = lightPos + lightDir * Extend;
- x = newPos.x;
- y = newPos.y;
- z = newPos.z;
- }
- void CVector::ExtendVertexPos(CVector lightPos, float Extend)
- {
- CVector lightDir; // Direction of the light to the vertex position.
- CVector newPos; // New extended vertex position to make up the shadow volume.
- // Get the light direction from the vertex position and the light position.
- lightDir = CVector(x, y, z) - lightPos;
- // Now that we know where its going we add it to the position of the light so
- // we get the correct, new position. We multiply it by a passed it value to
- // give the volume some distance or things won't come out quite as we want.
- newPos = lightPos + lightDir * Extend;
- x = newPos.x;
- y = newPos.y;
- z = newPos.z;
- }
- CVector CVector::GetRotatedX(double angle)
- {
- float sinAngle = (float)sin(M_PI * angle / 180);
- float cosAngle = (float)cos(M_PI * angle / 180);
- return CVector(x, y * cosAngle - z * sinAngle, y * sinAngle + z * cosAngle);
- }
- CVector CVector::GetRotatedY(double angle)
- {
- float sinAngle = (float)sin(M_PI * angle / 180);
- float cosAngle = (float)cos(M_PI * angle / 180);
- return CVector(x * cosAngle + z * sinAngle, y, -x * sinAngle + z * cosAngle);
- }
- CVector CVector::GetRotatedZ(double angle)
- {
- float sinAngle = (float)sin(M_PI * angle / 180);
- float cosAngle = (float)cos(M_PI * angle / 180);
- return CVector(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z);
- }
- CVector CVector::GetRotatedAxis(double angle, CVector axis)
- {
- if(angle == 0.0) return(*this);
- axis.Normal();
- CVector RotationRow1, RotationRow2, RotationRow3;
- double newAngle = M_PI * angle / 180;
- float sinAngle = (float)sin(newAngle);
- float cosAngle = (float)cos(newAngle);
- float oneSubCos = 1.0f - cosAngle;
- RotationRow1.x = (axis.x) * (axis.x) + cosAngle * (1 - (axis.x) * (axis.x));
- RotationRow1.y = (axis.x) * (axis.y) * (oneSubCos) - sinAngle * axis.z;
- RotationRow1.z = (axis.x) * (axis.z) * (oneSubCos) + sinAngle * axis.y;
- RotationRow2.x = (axis.x) * (axis.y) * (oneSubCos) + sinAngle * axis.z;
- RotationRow2.y = (axis.y) * (axis.y) + cosAngle * (1 - (axis.y) * (axis.y));
- RotationRow2.z = (axis.y) * (axis.z) * (oneSubCos) - sinAngle * axis.x;
-
- RotationRow3.x = (axis.x) * (axis.z) * (oneSubCos) - sinAngle * axis.y;
- RotationRow3.y = (axis.y) * (axis.z) * (oneSubCos) + sinAngle * axis.x;
- RotationRow3.z = (axis.z) * (axis.z) + cosAngle * (1 - (axis.z) * (axis.z));
- return CVector(this->DotProduct3(RotationRow1),
- this->DotProduct3(RotationRow2),
- this->DotProduct3(RotationRow3));
- }
- void CVector::CalculateBinormalVector(CVector tangent, CVector normal)
- {
- this->CrossProduct(tangent, normal);
- }
- void CVector::ClampTo01()
- {
- CVector temp(x, y, z);
- temp.Normal();
- temp = temp * 0.5f + CVector(0.5f, 0.5f, 0.5f);
- x = temp.x;
- y = temp.y;
- z = temp.z;
- }
- // Copyright September 2003
- // All Rights Reserved!
- // Allen Sherrod
- // ProgrammingAce@UltimateGameProgramming.com
- // www.UltimateGameProgramming.com