|
#include <iostream> |
|
#include <cmath> |
|
#include <sstream> |
|
|
|
using namespace std; |
|
|
|
class Angle |
|
{ |
|
public: |
|
static constexpr double Pi = 3.1415926; |
|
enum type |
|
{ |
|
degree = 0, |
|
radian |
|
}; |
|
|
|
Angle() : degs(0), rads(0) {} |
|
Angle(const double &value, const type &t = degree) |
|
{ |
|
if(t == degree) |
|
{ |
|
degs = value; |
|
rads = (value*Pi)/180; |
|
} |
|
else if(t == radian) |
|
{ |
|
rads = value; |
|
degs = (value*180)/Pi; |
|
} |
|
} |
|
Angle(const Angle ©) : degs(copy.degrees()), rads(copy.radians()) {} |
|
|
|
Angle &operator=(const Angle &rhs) |
|
{ |
|
degs = rhs.degrees(); |
|
rads = rhs.radians(); |
|
return *this; |
|
} |
|
|
|
double degrees() const { return degs; } |
|
double radians() const { return rads; } |
|
|
|
private: |
|
double degs, rads; |
|
}; |
|
Angle operator+(const Angle &lhs, const Angle &rhs) |
|
{ |
|
return Angle(lhs.degrees() + rhs.degrees()); |
|
} |
|
Angle operator+(const Angle &lhs, const double &rhs) |
|
{ |
|
return Angle(lhs.degrees() + rhs); |
|
} |
|
Angle operator-(const Angle &lhs, const Angle &rhs) |
|
{ |
|
return Angle(lhs.degrees() - rhs.degrees()); |
|
} |
|
Angle operator-(const Angle &lhs, const double &rhs) |
|
{ |
|
return Angle(lhs.degrees() - rhs); |
|
} |
|
std::ostream &operator<<(std::ostream &os, const Angle &rhs) |
|
{ |
|
os << rhs.radians(); |
|
return os; |
|
} |
|
|
|
|
|
|
|
template<class T> |
|
class vector2d |
|
{ |
|
public: |
|
typedef T value_type; |
|
|
|
vector2d() |
|
: component_x(0) |
|
, component_y(0) {} |
|
vector2d(const value_type &x, const value_type &y) |
|
: component_x(x) |
|
, component_y(y) {} |
|
vector2d(const value_type &resultant, const Angle &angle) |
|
: component_x(resultant*cos(angle.radians())) |
|
, component_y(resultant*sin(angle.radians())) {} |
|
vector2d(const vector2d ©) //copy ctor |
|
: component_x(copy.x()) |
|
, component_y(copy.y()) {} |
|
|
|
vector2d &operator=(const vector2d &rhs) |
|
{ |
|
component_x = rhs.x(); |
|
component_y = rhs.y(); |
|
} |
|
|
|
value_type x() const { return component_x; } |
|
value_type y() const { return component_y; } |
|
value_type resultant() const { return sqrt((component_x*component_x)+(component_y*component_y)); } |
|
Angle angle() const { return Angle(atan2(component_y, component_x), Angle::radian); } |
|
|
|
void setxy(const value_type &x, const value_type &y) |
|
{ |
|
component_x = x; |
|
component_y = y; |
|
} |
|
void setx(const value_type &x) { component_x = x; } |
|
void sety(const value_type &y) { component_y = y; } |
|
|
|
std::string toString() |
|
{ |
|
std::stringstream ss; |
|
ss << "<" << x() << ", " << y() << "> || " |
|
<< resultant() << " @ " << angle() << " rads"; |
|
return ss.str(); |
|
} |
|
|
|
private: |
|
value_type component_x, component_y; |
|
}; |
|
|
|
template<class T> |
|
vector2d<T> operator+(const vector2d<T> &lhs, const vector2d<T> &rhs) |
|
{ |
|
return vector2d<T>(lhs.x() + rhs.x(), lhs.y() + rhs.y()); |
|
} |
|
template<class T> |
|
vector2d<T> operator-(const vector2d<T> &lhs, const vector2d<T> &rhs) |
|
{ |
|
return vector2d<T>(lhs.x() - rhs.x(), lhs.y() - rhs.y()); |
|
} |
|
template<class T> |
|
std::ostream &operator<<(std::ostream &os, const vector2d<T> &rhs) |
|
{ |
|
os << "<" << rhs.x() << ", " << rhs.y() << ">"; |
|
return os; |
|
} |
|
|
|
typedef vector2d<int> vector2di; |
|
typedef vector2d<float> vector2df; |
|
typedef vector2d<double> vector2dd; |
|
|
|
int main() |
|
{ |
|
cout << "-- Vector2d implementation" << endl; |
|
|
|
//vector defined by x and y components |
|
vector2dd componentVector(20, 50); |
|
|
|
//vector defined by length and angle |
|
vector2dd degreeVector(22, Angle(80)); |
|
|
|
//vector defined by length and angle measured in radians. |
|
vector2dd radianVector(75, Angle(1.5, Angle::radian)); |
|
|
|
|
|
//vector addition |
|
cout << "Addition: " << endl; |
|
cout << componentVector << " + " << radianVector |
|
<< " = " << (componentVector + radianVector).toString() << endl << endl; |
|
|
|
//vector subtraction |
|
cout << "Subtraction: " << endl; |
|
cout << degreeVector << " - " << componentVector |
|
<< " = " << (degreeVector - componentVector).toString() << endl; |
|
return 0; |
|
} |