Lines 287
##### Keywords
3d (3) vector (5)
##### Permissions
Viewable by Everyone
Editable by All Siafoo Users

# vector3.h 0

 In Brief This is a 3D vector class that can convert between different coordinate systems.
 Language C++
# 's
`  1#ifndef VECTOR3_H  2#define VECTOR3_H  3  4// this class defines a 3D vector in different coordinate systems  5  6  7#include <cmath>  8#include <iostream>  9#include <assert> 10#include "angle.h" 11 12namespace Math { 13 14enum Coord3D { 15        X = 0, 16        Y, 17        Z 18}; 19 20 21class Vector3 22{ 23 24   private: 25      double data[3]; 26       27   public: 28      Vector3() 29      { 30         data[X] = 0; 31         data[Y] = 0; 32         data[Z] = 0; 33      } 34 35      Vector3(double x, double y, double z) 36      { 37         data[X] = x; 38         data[Y] = y; 39         data[Z] = z; 40      } 41 42      /// accessors and setters 43      double& operator[] (unsigned index) 44      { 45         return data[index]; 46      } 47 48      const double& operator[] (unsigned index) const 49      { 50         return data[index]; 51      } 52       53      /// Cylindrical Coordinates 54      double radius() const 55      { 56         return sqrt(data[X] * data[X] + data[Y] * data[Y]); 57      } 58       59      Angle theta() const  60      { 61         return Angle(atan2(data[Y], data[X])); 62      } 63       64      // z is the same as Z 65      void cylindricalCoordinates(double& radius, Angle& theta,  66                                  double& z) const 67      { 68         radius = radius(); 69         theta.setRadians(theta()); 70         z = data[Z]; 71      } 72 73      void cylindricalCoordinates(double& radius, double& theta,  74                                  double& z) const 75      { 76         radius = radius(); 77         theta = theta(); 78         z = data[Z]; 79      } 80       81      // set the radius in cylindrical coordinates, theta and z stay constant 82      void setRadius(double radius) 83      { 84         double curRadius = radius(); 85         if (0 == curRadius) 86         { 87            // we are going to project along the x-axis 88            data[X] = radius; 89         } else { 90            double scalar = radius / curRadius; 91            data[X] *= scalar; 92            data[Y] *= scalar; 93         } 94      } 95 96      // set theta in cylindrical coordinates, radius and Z stay the same 97      // set theta in spherical coordinates as well... 98      void setTheta(const Angle& theta) 99      {100         double radius = radius();101         data[X] = radius * cos(theta.radians());102         data[Y] = radius * sin(theta.radians());103      }104105      void setCylindricalCoordinates(double radius, const Angle& theta, 106                                     double z = 0)107      {108         data[X] = radius * cos(theta.radians());109         data[Y] = radius * sin(theta.radians());110         data[Z] = z;111      }112113      /// Spherical Coordinates114      // equations for theta should be the same115      Angle phi() const116      {117         // TODO: I think this is correct, but it should be checked118         return Angle(atan2(radius(), data[Z]));119      }120      121      // set phi without changing rho or theta122      void setPhi(const Angle& phi)123      {124         // TODO: figure out how to do this...125      }126127      double rho() const128      {129         return magnitude();130      }131132      // set rho without changing theta or phi133      void setRho(double rho)134      {135         double curRho = rho();136         if (0 == curRho)137         {138            // we are just going to project rho along the x-axis139            data[X] = rho;140         } else {141            *this *= rho / curRho;142         }143      }144145      void sphericalCoordinates(double& rho, Angle& theta, Angle& phi)146      {147         rho = rho();148         theta = theta();149         phi = phi();150      }151152      void setSphericalCoordinates(double rho, const Angle& theta, 153                                   const Angle& phi)154      {155         // radius in cylindrical coordinates156         double radius = rho * sin(phi.radians());157         // solve for z158         double z = rho * cos(phi.radians());159         // use the cylindrical coordinate function160         setCylindricalCoordinates(radius, theta, z);161      }162163      /// operators164      Vector3 operator - ()165      {166         return Vector3(-data[X], -data[Y], -data[Z]);167      }168169      Vector3& operator = (const Vector3& rhs)170      {171         data[X] = rhs.data[X];172         data[Y] = rhs.data[Y];173         data[Z] = rhs.data[Z];174         return *this;175      }176177      Vector3& operator += (const Vector3& rhs)178      {179         data[X] += rhs.data[X];180         data[Y] += rhs.data[Y];181         data[Z] += rhs.data[Z];182         return *this;183      }184185      Vector3& operator -= (const Vector3& rhs)186      {187         data[X] -= rhs.data[X];188         data[Y] -= rhs.data[Y];189         data[Z] -= rhs.data[Z];190         return *this;191      }192193      Vector3& operator *= (const double rhs)194      {195         data[X] *= rhs;196         data[Y] *= rhs;197         data[Z] *= rhs;198         return *this;199      }200201      Vector3& operator /= (const double rhs)202      {203         data[X] /= rhs;204         data[Y] /= rhs;205         data[Z] /= rhs;206         return *this;207      }208209      double magnitudeSquared() const210      {211         return data[X]*data[X] + data[Y]*data[Y] + data[Z]*data[Z];212      }213214      double magnitude() const215      {216         return std::sqrt(data[X]*data[X] + data[Y]*data[Y] + data[Z]*data[Z]);217      }218219      Vector3& normalize()220      {221         double scale = magnitude();222223         // I cannot find any math resources online that say normalizing 224         // a zero-vector is well defined. 225         assert(scale != 0.0);226227         *this /= scale;228229         return *this;230      }231232      Vector3& cross(const Vector3 &rhs)233      {234         data[X] = data[Y]*rhs[Z] - data[Z]*rhs[Y];235         data[Y] = data[Z]*rhs[X] - data[X]*rhs[Z];236         data[Z] = data[X]*rhs[Y] - data[Y]*rhs[X];237         return *this;238      }239240   private:241//      template <class Archive>242//      void serialize(Archive &ar, const unsigned int version)243//      {244//          ar & data[X];245//          ar & data[Y];246//          ar & data[Z];247//      }248};249250inline std::ostream& operator << (std::ostream &os, const Vector3 &v)251{252   return os << '(' << v[X] << ", " << v[Y] << ", " << v[Z] << ')';253}254255inline bool operator == (const Vector3 &lhs, const Vector3 &rhs)256{257   return lhs[X] == rhs[X]258      && lhs[Y] == rhs[Y]259      && lhs[Z] == rhs[Z];260}261262inline bool operator != (const Vector3 &lhs, const Vector3 &rhs)263{264   return lhs[X] != rhs[X]265      || lhs[Y] != rhs[Y]266      || lhs[Z] != rhs[Z];267}268269inline Vector3 operator + (const Vector3 &lhs, const Vector3 &rhs)270{271   Vector3 ret(lhs);272   ret += rhs;273   return ret;274}275276inline Vector3 operator - (const Vector3 &lhs, const Vector3 &rhs)277{278   Vector3 ret(lhs);279   ret -= rhs;280   return ret;281}282283inline Vector3 operator * (const Vector3 &lhs, const double rhs)284{285   Vector3 ret(lhs);286   ret *= rhs;287   return ret;288}289290inline Vector3 operator * (const double lhs, const Vector3 &rhs)291{292   Vector3 ret(rhs);293   ret *= lhs;294   return ret;295}296297inline Vector3 operator / (const Vector3 &lhs, const double rhs)298{299   Vector3 ret(lhs);300   ret /= rhs;301   return ret;302}303304inline double abs(const Vector3 &orig)305{306   return orig.magnitude();307}308309inline Vector3 normal(const Vector3 &orig)310{311   Vector3 ret(orig);312   ret.normalize();313   return ret;314}315316inline double dot(const Vector3 &u, const Vector3 &v)317{318   return u[X]*v[X] + u[Y]*v[Y] + u[Z]*v[Z];319}320321inline Vector3 cross(const Vector3 &u, const Vector3 &v)322{323   Vector3 ret;324325   ret[X] = u[Y]*v[Z] - u[Z]*v[Y];326   ret[Y] = u[Z]*v[X] - u[X]*v[Z];327   ret[Z] = u[X]*v[Y] - u[Y]*v[X];328   return ret;329}330331} // namespace Math332333// let's save some keystrokes334using Math::Vector3;335336337#endif`

This is a 3D vector class that can convert between different coordinate systems.