Last time we made a class to encapsulate a 2D vector with floating point entries. In this post we'll finish up with the 3 and 4 dimensional vector classes. None of these will be particularly useful however, until we make a matrix class that can transform these vectors.
So let's get started.
vector3f.h
#ifndef _VECTOR3F_H_ #define _VECTOR3F_H_ class vector3f { private: float elements[3]; public: static const int SIZE; vector3f(float x = 0.0f, float y = 0.0f, float z = 0.0f); vector3f(const vector3f& other); vector3f normal() const; void normalize(); float length() const; static float dot(const vector3f& vector1, const vector3f& vector2); static vector3f cross(const vector3f& vector1, const vector3f& vector2); vector3f& operator=(const vector3f& other); vector3f operator-() const; vector3f operator*(float scalar) const; vector3f operator/(float scalar) const; friend vector3f operator+(const vector3f& vector1, const vector3f& vector2); friend vector3f operator-(const vector3f& vector1, const vector3f& vector2); friend vector3f operator*(float scalar, const vector3f& vector); friend bool operator==(const vector3f& vector1, const vector3f& vector2); friend bool operator!=(const vector3f& vector1, const vector3f& vector2); float& operator[](int index); }; #endif
You'll notice we have a function that the vector2f class does not: cross
This is the cross product of two 3D vectors which produces a vector perpendicular to both input vectors in a direction determined by the right hand rule. It is only defined for 3 dimensional vectors.
vector3f.cpp
#include "vector3f.h" #include <cmath> const int vector3f::SIZE = 3; vector3f::vector3f(float x, float y, float z) { elements[0] = x; elements[1] = y; elements[2] = z; } vector3f::vector3f(const vector3f& other) { elements[0] = other.elements[0]; elements[1] = other.elements[1]; elements[2] = other.elements[2]; } vector3f vector3f::normal() const { float l = length(); return vector3f(elements[0] / l, elements[1] / l, elements[2] / l); } void vector3f::normalize() { float l = length(); elements[0] /= l; elements[1] /= l; elements[2] /= l; } float vector3f::length() const { return std::sqrt(elements[0] * elements[0] + elements[1] * elements[1] + elements[2] * elements[2]); } float vector3f::dot(const vector3f& vector1, const vector3f& vector2) { return vector1.elements[0] * vector2.elements[0] + vector1.elements[1] * vector2.elements[1] + vector1.elements[2] * vector2.elements[2]; } vector3f vector3f::cross(const vector3f& vector1, const vector3f& vector2) { return vector3f(vector1.elements[1] * vector2.elements[2] - vector1.elements[2] * vector2.elements[0], vector1.elements[2] * vector2.elements[0] - vector1.elements[0] * vector2.elements[2], vector1.elements[0] * vector2.elements[1] - vector1.elements[1] * vector2.elements[0]); } vector3f& vector3f::operator=(const vector3f& other) { if (this != &other) { elements[0] = other.elements[0]; elements[1] = other.elements[1]; elements[2] = other.elements[2]; } return *this; } vector3f vector3f::operator-() const { return vector3f(-elements[0], -elements[1], -elements[2]); } vector3f vector3f::operator*(float scalar) const { return vector3f(scalar * elements[0], scalar * elements[1], scalar * elements[2]); } vector3f vector3f::operator/(float scalar) const { return vector3f(elements[0] / scalar, elements[1] / scalar, elements[2] / scalar); } vector3f operator+(const vector3f& vector1, const vector3f& vector2) { return vector3f(vector1.elements[0] + vector2.elements[0], vector1.elements[1] + vector2.elements[1], vector1.elements[2] * vector2.elements[2]); } vector3f operator-(const vector3f& vector1, const vector3f& vector2) { return vector3f(vector1.elements[0] - vector2.elements[0], vector1.elements[1] - vector2.elements[1], vector1.elements[2] - vector2.elements[2]); } vector3f operator*(float scalar, const vector3f& vector) { return vector3f(scalar * vector.elements[0], scalar * vector.elements[1], scalar * vector.elements[2]); } bool operator==(const vector3f& vector1, const vector3f& vector2) { return ((vector1.elements[0] == vector2.elements[0]) && (vector1.elements[1] == vector2.elements[1]) && vector1.elements[2] == vector2.elements[2]); } bool operator!=(const vector3f& vector1, const vector3f& vector2) { return ((vector1.elements[0] != vector2.elements[0]) || (vector1.elements[1] != vector2.elements[1]) || vector1.elements[2] != vector2.elements[2]); } float& vector3f::operator[](int index) { return elements[index]; }
vector4f.h
#ifndef _VECTOR4F_H_ #define _VECTOR4F_H_ class KOGAPI vector4f { private: float elements[4]; public: static const int SIZE; vector4f(float x = 0.0f, float y = 0.0f, float z = 0.0f, float w = 0.0f); vector4f(const vector4f& other); vector4f normal() const; void normalize(); float length() const; static float dot(const vector4f& vector1, const vector4f& vector2); vector4f& operator=(const vector4f& other); vector4f operator-() const; vector4f operator*(float scalar) const; vector4f operator/(float scalar) const; friend vector4f operator+(const vector4f& vector1, const vector4f& vector2); friend vector4f operator-(const vector4f& vector1, const vector4f& vector2); friend vector4f operator*(float scalar, const vector4f& vector); friend bool operator==(const vector4f& vector1, const vector4f& vector2); friend bool operator!=(const vector4f& vector1, const vector4f& vector2); float& operator[](int index); }; #endif
vector4f.cpp
#include "vector4f.h" #include <cmath> vector4f::vector4f(float x, float y, float z, float w) { elements[0] = x; elements[1] = y; elements[2] = z; elements[3] = w; } vector4f::vector4f(const vector4f& other) { elements[0] = other.elements[0]; elements[1] = other.elements[1]; elements[2] = other.elements[2]; elements[3] = other.elements[3]; } vector4f vector4f::normal() const { float l = length(); return vector4f(elements[0] / l, elements[1] / l, elements[2] / l, elements[3] / l); } void vector4f::normalize() { float l = length(); elements[0] /= l; elements[1] /= l; elements[2] /= l; elements[3] /= l; } float vector4f::length() const { return std::sqrt(elements[0] * elements[0] + elements[1] * elements[1] + elements[2] * elements[2] + elements[3] * elements[3]); } float vector4f::dot(const vector4f& vector1, const vector4f& vector2) { return vector1.elements[0] * vector2.elements[0] + vector1.elements[1] * vector2.elements[1] + vector1.elements[2] * vector2.elements[2] + vector1.elements[3] * vector2.elements[3]; } vector4f& vector4f::operator=(const vector4f& other) { if (this != &other) { elements[0] = other.elements[0]; elements[1] = other.elements[1]; elements[2] = other.elements[2]; elements[3] = other.elements[3]; } return *this; } vector4f vector4f::operator-() const { return vector4f(-elements[0], -elements[1], -elements[2], -elements[3]); } vector4f vector4f::operator*(float scalar) const { return vector4f(scalar * elements[0], scalar * elements[1], scalar * elements[2], scalar * elements[3]); } vector4f vector4f::operator/(float scalar) const { return vector4f(elements[0] / scalar, elements[1] / scalar, elements[2] / scalar, elements[3] / scalar); } vector4f operator+(const vector4f& vector1, const vector4f& vector2) { return vector4f(vector1.elements[0] + vector2.elements[0], vector1.elements[1] + vector2.elements[1], vector1.elements[2] * vector2.elements[2], vector1.elements[3] + vector2.elements[3]); } vector4f operator-(const vector4f& vector1, const vector4f& vector2) { return vector4f(vector1.elements[0] - vector2.elements[0], vector1.elements[1] - vector2.elements[1], vector1.elements[2] - vector2.elements[2], vector1.elements[3] - vector2.elements[3]); } vector4f operator*(float scalar, const vector4f& vector) { return vector4f(scalar * vector.elements[0], scalar * vector.elements[1], scalar * vector.elements[2], scalar * vector.elements[3]); } bool operator==(const vector4f& vector1, const vector4f& vector2) { return ((vector1.elements[0] == vector2.elements[0]) && (vector1.elements[1] == vector2.elements[1]) && vector1.elements[2] == vector2.elements[2] && vector1.elements[3] == vector2.elements[3]); } bool operator!=(const vector4f& vector1, const vector4f& vector2) { return ((vector1.elements[0] != vector2.elements[0]) || (vector1.elements[1] != vector2.elements[1]) || (vector1.elements[2] != vector2.elements[2]) || (vector1.elements[3] != vector2.elements[3])); } float& vector4f::operator[](int index) { return elements[index]; }
That's it for now. Next post we'll set up the matrix and quaternion class.
Questions are always welcome and if you have an idea for a tutorial or series you'd like to see feel free to comment it!.