5 #include <cmath> |
5 #include <cmath> |
6 |
6 |
7 /** |
7 /** |
8 * A 2D Vector class. Implements standard vector operations. |
8 * A 2D Vector class. Implements standard vector operations. |
9 */ |
9 */ |
10 template <typename T> |
10 template <typename T> class VectorType { |
11 class _Vector { |
|
12 public: |
11 public: |
|
12 /** Horizontal component */ |
13 T x; |
13 T x; |
|
14 /** Vertical component */ |
14 T y; |
15 T y; |
15 |
16 |
16 /** |
17 /** |
17 * Default constructor. |
18 * Default constructor. Values are zero |
18 */ |
19 */ |
19 _Vector() : x(0), y(0) {} |
20 VectorType() : |
|
21 x(0), y(0) |
|
22 { |
|
23 |
|
24 } |
20 |
25 |
21 /** |
26 /** |
22 * Constuctor. |
27 * Scalar constuctor. |
23 * |
28 * |
24 * @param x Initial x-coordinate |
29 * @param x Initial x-coordinate |
25 * @param y Initial y-coordinate |
30 * @param y Initial y-coordinate |
26 */ |
31 */ |
27 _Vector(T x, T y) : x(x), y(y) {} |
32 VectorType (const T &x, const T &y) : |
|
33 x(x), y(y) |
|
34 { |
|
35 |
|
36 } |
28 |
37 |
29 /** |
38 /** |
30 * Copy constructor. |
39 * Copy constructor. |
31 * |
40 * |
32 * @param v Vector to be copied. |
41 * @param v Vector to be copied. |
33 */ |
42 */ |
34 _Vector(const _Vector &v) : x(v.x), y(v.y) {} |
43 VectorType (const VectorType &v) : |
35 |
44 x(v.x), |
36 // Operator declarations |
45 y(v.y) |
37 void operator=(const _Vector &v) { |
46 { |
38 this->x = v.x; |
47 |
39 this->y = v.y; |
|
40 } |
|
41 _Vector operator+(const _Vector &v) const { |
|
42 return _Vector(this->x+v.x, this->y+v.y); |
|
43 } |
|
44 _Vector operator-(const _Vector &v) const { |
|
45 return _Vector(this->x-v.x, this->y-v.y); |
|
46 } |
|
47 _Vector operator- (void) const { |
|
48 return _Vector(-this->x, -this->y); |
|
49 } |
|
50 _Vector operator*(const T &scalar) const { |
|
51 return _Vector(this->x*scalar, this->y*scalar); |
|
52 } |
|
53 T operator*(const _Vector &v) const { |
|
54 return (this->x*v.x + this->y*v.y); |
|
55 } |
|
56 _Vector operator/ (const T &d) const { |
|
57 return _Vector(this->x / d, this->y / d); |
|
58 } |
|
59 void operator+=(const _Vector &v) { |
|
60 *this = *this + v; |
|
61 } |
|
62 void operator-=(const _Vector &v) { |
|
63 *this = *this - v; |
|
64 } |
|
65 void operator*=(const T &scalar) { |
|
66 *this = *this * scalar; |
|
67 } |
|
68 void operator/=(const T &scalar) { |
|
69 *this = *this / scalar; |
|
70 } |
48 } |
71 |
49 |
72 // Other operations |
50 /** |
73 T length() const { |
51 * @name Standard operators |
|
52 * |
|
53 * @{ |
|
54 */ |
|
55 VectorType& operator= (const VectorType &v) { |
|
56 x = v.x; |
|
57 y = v.y; |
|
58 |
|
59 return *this; |
|
60 } |
|
61 |
|
62 VectorType operator+ (const VectorType &v) const { |
|
63 return VectorType(x + v.x, y + v.y); |
|
64 } |
|
65 |
|
66 VectorType operator- (const VectorType &v) const { |
|
67 return VectorType(x - v.x, y - v.y); |
|
68 } |
|
69 |
|
70 /** Unary minus (v + -v = 0) */ |
|
71 VectorType operator- (void) const { |
|
72 return VectorType(-x, -y); |
|
73 } |
|
74 |
|
75 /** Scalar multiplication */ |
|
76 VectorType operator* (const T &scalar) const { |
|
77 return VectorType(x * scalar, y * scalar); |
|
78 } |
|
79 |
|
80 /** Scalar division */ |
|
81 VectorType operator/ (const T &scalar) const { |
|
82 return VectorType(x / scalar, y / scalar); |
|
83 } |
|
84 |
|
85 /** Dot product */ |
|
86 T operator* (const VectorType &v) const { |
|
87 return (x * v.x + y * v.y); |
|
88 } |
|
89 |
|
90 void operator+= (const VectorType &v) { |
|
91 x += v.x; |
|
92 y += v.y; |
|
93 } |
|
94 |
|
95 void operator-= (const VectorType &v) { |
|
96 x -= v.x; |
|
97 y -= v.y; |
|
98 } |
|
99 |
|
100 void operator*= (const T &scalar) { |
|
101 x *= scalar; |
|
102 y *= scalar; |
|
103 } |
|
104 |
|
105 void operator/= (const T &scalar) { |
|
106 x /= scalar; |
|
107 y /= scalar; |
|
108 } |
|
109 |
|
110 /** |
|
111 * XXX: This needs to do some rounding for float-vectors |
|
112 */ |
|
113 bool operator== (const VectorType &other) const { |
|
114 return (x == other.x) && (y == other.y); |
|
115 } |
|
116 |
|
117 /** |
|
118 * XXX: This needs to do some rounding for float-vectors |
|
119 */ |
|
120 bool operator!= (const VectorType &other) const { |
|
121 return (x != other.x) || (y != other.y); |
|
122 } |
|
123 |
|
124 // @} |
|
125 |
|
126 /** |
|
127 * Vector scalar length |
|
128 */ |
|
129 T length (void) const { |
74 return sqrt(sqrLength()); |
130 return sqrt(sqrLength()); |
75 } |
131 } |
76 T sqrLength() const { |
132 |
77 return (this->x * this->x) + (this->y * this->y); |
133 /** |
|
134 * Vector scalar length, squared |
|
135 */ |
|
136 T sqrLength (void) const { |
|
137 return (x * x) + (y * y); |
78 } |
138 } |
79 _Vector roundToInt() const { |
139 |
80 return _Vector((int)(x), (int)(y)); |
140 /** |
|
141 * XXX: should be replaced with a working operator== implementation |
|
142 * |
|
143 * This doesn't actually *round*, it *truncates* |
|
144 */ |
|
145 VectorType roundToInt (void) const { |
|
146 return VectorType((int)(x), (int)(y)); |
|
147 } |
|
148 |
|
149 /** |
|
150 * Test for a zero-length vector. |
|
151 * |
|
152 * XXX: this is currently only used when testing for Vector(0, 0), probably breaks otherwise |
|
153 */ |
|
154 bool zero (void) const { |
|
155 return x == 0 && y == 0; |
81 } |
156 } |
82 |
157 |
83 // test Vectors as booleans |
|
84 // XXX: comparing floats against zero... is a bad idea? |
|
85 bool zero(void) const { |
|
86 return x == 0 && y == 0; |
|
87 } |
|
88 }; |
158 }; |
89 |
159 |
90 // Unary operators |
160 /** |
91 template<typename T> |
161 * @name Postfix operators |
92 _Vector<T> operator*(const T &scalar, const _Vector<T> v) { |
162 * Operators with the vector as the second argument :) |
|
163 * |
|
164 * @{ |
|
165 */ |
|
166 template<typename T> VectorType<T> operator* (const T &scalar, const VectorType<T> &v) { |
93 return (v * scalar); |
167 return (v * scalar); |
94 } |
168 } |
95 |
169 |
96 // Comparison operators |
170 /** |
97 template<typename T> |
171 * Make vectors printable |
98 bool operator==(const _Vector<T> &v1, const _Vector<T> &v2) { |
172 */ |
99 return ((v1.x == v2.x) && (v1.y == v2.y)); |
173 template<typename T> std::ostream& operator<< (std::ostream &s, const VectorType<T> &v) { |
100 } |
174 return s << "(" << v.x << ", " << v.y << ")"; |
101 template<typename T> |
|
102 bool operator!=(const _Vector<T> &v1, const _Vector<T> &v2) { |
|
103 return !(v1 == v2); |
|
104 } |
|
105 |
|
106 // Output operator |
|
107 template<typename T> |
|
108 std::ostream& operator<<(std::ostream &s, const _Vector<T> &v) { |
|
109 return s<<"("<<v.x<<", "<<v.y<<")"; |
|
110 } |
175 } |
111 |
176 |
112 #endif |
177 #endif |