Saturday, January 21, 2017

Orbital Aero Model: Vector Class

This is one of a series of posts for how orientations and rotations are handled in the orbital aero model (original post in series). This Vector class ties in with the Euler, Quaternion, and Matrix classes also posted.

This is an update of my original Vector class posted in 2015.

Vector.h


#pragma once

template <typename T> int sgn(T val)
{
return (T(0) < val) - (val < T(0));
}

class Euler;
class Quaternion;
class Matrix;

class Vector
{
private:

public:
double x;
double y;
double z;

// Create a vector (0,0,0).
Vector();

// Create an vector form a given X, Y, and Z.
Vector(const double newX, const double newY, const double newZ);

// Sets all value of a vector to a given value.
Vector &operator = (const double newValue);

// Sets the vector to another vector.
Vector &operator = (const Vector &thatVector);

// Gets the reverse of the vector.
Vector operator - ();

// Adds the vector to another vector.
Vector operator + (const Vector &vectorToAdd) const;

// Subtracts the vector by another vector.
Vector operator - (const Vector &vectorToSubtract) const;

// Multiplies the vector by a value.
Vector operator * (const double valueToMultiply) const;

// Multiplies the vector by another vector.
Vector operator * (const Vector &vectorToMultiply) const;

// Multiplies the vector to a matrix.
Vector operator * (const Matrix &matrixToMultiply) const;

// Divides the vector by a value.
Vector operator / (const double valueToDivide) const;

// Adds the vector to another vector.
Vector &operator += (const Vector &vectorToAdd);

// Subtracts the vector by another vector.
Vector &operator -= (const Vector &vectorToSubtract);

// Multiplies the vector by another vector.
Vector &operator *= (double valueToMultiply);

// Divides the vector by another vector.
Vector &operator /= (double valueToDivide);

// Get the magnitude of the vector.
double magnitude() const;

// Get the unit vector.
Vector unit() const;

// Get a vector representing the sign of each component.
Vector sign() const;

// Get the dot product of two vectors.
static double dotProduct(const Vector &vector1, const Vector &vector2);

// Get the cross product of two vectors.
static Vector crossProduct(const Vector &vector1, const Vector &vector2);

// Get the vector rotated by a quaternion.
Vector rotatedBy(const Quaternion &rotationQuat) const;

// Get the vector rotated by euler angles.
Vector rotatedBy(const Euler &rotationAngles_radians) const;
};

Vector.cpp


#include "math.h"
#include "Quaternion.h"
#include "Matrix.h"
#include "Euler.h"
#include "Vector.h"

// Create a vector (0,0,0).
Vector::Vector()
{
this->x = 0.0;
this->y = 0.0;
this->z = 0.0;
return;
}

// Create an vector form a given X, Y, and Z.
Vector::Vector(const double newX, const double newY, const double newZ)
{
this->x = newX;
this->y = newY;
this->z = newZ;
return;
}

// Sets all value of a vector to a given value.
Vector &Vector::operator = (const double newValue)
{
this->x = newValue;
this->y = newValue;
this->z = newValue;
return *this;
}

// Sets the vector to another vector.
Vector &Vector::operator = (const Vector &thatVector)
{
// Protect against self-assignment. (Otherwise bad things happen when it's reading from memory it has cleared.)
if (this != &thatVector)
{
this->x = thatVector.x;
this->y = thatVector.y;
this->z = thatVector.z;
}
return *this;
}

// Gets the reverse of the vector.
Vector Vector::operator - ()
{
return Vector(-this->x, -this->y, -this->z);
}

// Adds the vector to another vector.
Vector Vector::operator + (const Vector &vectorToAdd) const
{
return Vector(this->x + vectorToAdd.x, this->y + vectorToAdd.y, this->z + vectorToAdd.z);
}

// Subtracts the vector by another vector.
Vector Vector::operator - (const Vector &vectorToSubtract) const
{
return Vector(this->x - vectorToSubtract.x, this->y - vectorToSubtract.y, this->z - vectorToSubtract.z);
}

// Multiplies the vector by a value.
Vector Vector::operator * (const double valueToMultiply) const
{
return Vector(this->x * valueToMultiply, this->y * valueToMultiply, this->z * valueToMultiply);
}

// Multiplies the vector by another vector.
Vector Vector::operator * (const Vector &vectorToMultiply) const
{
return Vector(this->x * vectorToMultiply.x, this->y * vectorToMultiply.y, this->z * vectorToMultiply.z);
}

// Multiplies the vector to a matrix.
Vector Vector::operator * (const Matrix &matrixToMultiply) const
{
return Vector((matrixToMultiply.value[0][0] * this->x) + (matrixToMultiply.value[0][1] * this->y) + (matrixToMultiply.value[0][2] * this->z),
                  (matrixToMultiply.value[1][0] * this->x) + (matrixToMultiply.value[1][1] * this->y) + (matrixToMultiply.value[1][2] * this->z),
             (matrixToMultiply.value[2][0] * this->x) + (matrixToMultiply.value[2][1] * this->y) + (matrixToMultiply.value[2][2] * this->z));
}

// Divides the vector by a value.
Vector Vector::operator / (const double valueToDivide) const
{
if (valueToDivide != 0.0)
{
return Vector(this->x / valueToDivide, this->y / valueToDivide, this->z / valueToDivide);
}
else
{
return Vector(this->x, this->y, this->z);
}
}

// Adds the vector to another vector.
Vector &Vector::operator += (const Vector &vectorToAdd)
{
this->x += vectorToAdd.x;
this->y += vectorToAdd.y;
this->z += vectorToAdd.z;
return *this;
}

// Subtracts the vector by another vector.
Vector &Vector::operator -= (const Vector &vectorToSubtract)
{
this->x -= vectorToSubtract.x;
this->y -= vectorToSubtract.y;
this->z -= vectorToSubtract.z;
return *this;
}

// Multiplies the vector by another vector.
Vector &Vector::operator *= (double valueToMultiply)
{
this->x *= valueToMultiply;
this->y *= valueToMultiply;
this->z *= valueToMultiply;
return *this;
}

// Divides the vector by another vector.
Vector &Vector::operator /= (double valueToDivide)
{
if (valueToDivide != 0.0)
{
this->x /= valueToDivide;
this->y /= valueToDivide;
this->z /= valueToDivide;
}
return *this;
}

// Get the magnitude of the vector.
double Vector::magnitude() const
{
return sqrt( (this->x * this->x) + (this->y * this->y) + (this->z * this->z) );
}

// Get the unit vector.
Vector Vector::unit() const
{
double mag = this->magnitude();

Vector unitVector;
if (mag > 0)
{
unitVector.x = this->x / mag;
unitVector.y = this->y / mag;
unitVector.z = this->z / mag;
}
else
{
unitVector.x = 1.0;
unitVector.y = 0.0;
unitVector.z = 0.0;
}

return unitVector;
}

// Get a vector representing the sign of each component.
Vector Vector::sign() const
{
Vector signVector;
signVector.x = sgn(this->x);
signVector.y = sgn(this->y);
signVector.z = sgn(this->z);
return signVector;
}

// Get the dot product of two vectors.
double Vector::dotProduct(const Vector &vector1, const Vector &vector2)
{
return ((vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z));
}

// Get the cross product of two vectors.
Vector Vector::crossProduct(const Vector &vector1, const Vector &vector2)
{
Vector crossVector;
crossVector.x = (vector1.y * vector2.z) - (vector1.z * vector2.y);
crossVector.y = (vector1.z * vector2.x) - (vector1.x * vector2.z);
crossVector.z = (vector1.x * vector2.y) - (vector1.y * vector2.x);
return crossVector;
}

// Get the vector rotated by a quaternion.
Vector Vector::rotatedBy(const Quaternion &rotationQuat) const
{
Matrix transformationMatrix = rotationQuat.transformationMatrix();
return (*this) * transformationMatrix;
}

// Get the vector rotated by euler angles.
Vector Vector::rotatedBy(const Euler &rotationAngles_radians) const
{
Matrix transformationMatrix = rotationAngles_radians.transformationMatrix();
return (*this) * transformationMatrix;
}


Copyright (c) 2017 Clinton Kam
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

No comments:

Post a Comment