]> Shamusworld >> Repos - architektonas/blob - src/vector.cpp
e992bbffd53aa5496bffde85c0ff6b543f4891fd
[architektonas] / src / vector.cpp
1 //\r
2 // vector.cpp: Various structures used for 3 dimensional imaging\r
3 //\r
4 // by James Hammons\r
5 // (C) 2006 Underground Software\r
6 //\r
7 // JLH = James L. Hammons <jlhamm@acm.org>\r
8 //\r
9 // WHO  WHEN        WHAT\r
10 // ---  ----------  ------------------------------------------------------------\r
11 // JLH  09/19/2006  Created this file\r
12 // JLH  03/22/2011  Moved implementation of constructor from header to here\r
13 // JLH  04/02/2011  Fixed divide-by-zero bug in Unit(), added Angle() function\r
14 //\r
15 \r
16 #include "vector.h"\r
17 \r
18 #include <math.h>                                                               // For sqrt()\r
19 #include "mathconstants.h"\r
20 \r
21 \r
22 // Vector implementation\r
23 \r
24 Vector::Vector(double xx/*= 0*/, double yy/*= 0*/, double zz/*= 0*/): x(xx), y(yy), z(zz)\r
25 {\r
26 }\r
27 \r
28 Vector::Vector(Vector head, Vector tail): x(head.x - tail.x), y(head.y - tail.y), z(head.z - tail.z)\r
29 {\r
30 }\r
31 \r
32 Vector Vector::operator=(Vector const v)\r
33 {\r
34         x = v.x, y = v.y, z = v.z;\r
35 \r
36         return *this;\r
37 }\r
38 \r
39 Vector Vector::operator+(Vector const v)\r
40 {\r
41         return Vector(x + v.x, y + v.y, z + v.z);\r
42 }\r
43 \r
44 Vector Vector::operator-(Vector const v)\r
45 {\r
46         return Vector(x - v.x, y - v.y, z - v.z);\r
47 }\r
48 \r
49 // Unary negation\r
50 \r
51 Vector Vector::operator-(void)\r
52 {\r
53         return Vector(-x, -y, -z);\r
54 }\r
55 \r
56 // Vector x constant\r
57 \r
58 Vector Vector::operator*(double const v)\r
59 {\r
60         return Vector(x * v, y * v, z * v);\r
61 }\r
62 \r
63 // Vector x constant\r
64 \r
65 Vector Vector::operator*(float const v)\r
66 {\r
67         return Vector(x * v, y * v, z * v);\r
68 }\r
69 \r
70 // Vector / constant\r
71 \r
72 Vector Vector::operator/(double const v)\r
73 {\r
74         return Vector(x / v, y / v, z / v);\r
75 }\r
76 \r
77 // Vector / constant\r
78 \r
79 Vector Vector::operator/(float const v)\r
80 {\r
81         return Vector(x / v, y / v, z / v);\r
82 }\r
83 \r
84 // Vector (cross) product\r
85 \r
86 Vector Vector::operator*(Vector const v)\r
87 {\r
88         // a x b = [a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1]\r
89         return Vector((y * v.z) - (z * v.y), (z * v.x) - (x * v.z), (x * v.y) - (y * v.x));\r
90 }\r
91 \r
92 // Dot product\r
93 \r
94 double Vector::Dot(Vector const v)\r
95 {\r
96         return (x * v.x) + (y * v.y) + (z * v.z);\r
97 }\r
98 \r
99 \r
100 // Vector x constant, self assigned\r
101 \r
102 Vector& Vector::operator*=(double const v)\r
103 {\r
104         x *= v, y *= v, z *= v;\r
105 \r
106         return *this;\r
107 }\r
108 \r
109 // Vector / constant, self assigned\r
110 \r
111 Vector& Vector::operator/=(double const v)\r
112 {\r
113         x /= v, y /= v, z /= v;\r
114 \r
115         return *this;\r
116 }\r
117 \r
118 // Vector + vector, self assigned\r
119 \r
120 Vector& Vector::operator+=(Vector const v)\r
121 {\r
122         x += v.x, y += v.y, z += v.z;\r
123 \r
124         return *this;\r
125 }\r
126 \r
127 // Vector + constant, self assigned\r
128 \r
129 Vector& Vector::operator+=(double const v)\r
130 {\r
131         x += v, y += v, z += v;\r
132 \r
133         return *this;\r
134 }\r
135 \r
136 // Vector - vector, self assigned\r
137 \r
138 Vector& Vector::operator-=(Vector const v)\r
139 {\r
140         x -= v.x, y -= v.y, z -= v.z;\r
141 \r
142         return *this;\r
143 }\r
144 \r
145 // Vector - constant, self assigned\r
146 \r
147 Vector& Vector::operator-=(double const v)\r
148 {\r
149         x -= v, y -= v, z -= v;\r
150 \r
151         return *this;\r
152 }\r
153 \r
154 // Check for equality\r
155 bool Vector::operator==(Vector const v)\r
156 {\r
157         return (x == v.x && y == v.y && z == v.z ? true : false);\r
158 }\r
159 \r
160 // Check for inequality\r
161 bool Vector::operator!=(Vector const v)\r
162 {\r
163         return (x != v.x || y != v.y || z != v.z ? true : false);\r
164 }\r
165 \r
166 Vector Vector::Unit(void)\r
167 {\r
168         double mag = Magnitude();\r
169 \r
170         // If the magnitude of the vector is zero, then the Unit vector is undefined...\r
171         if (mag == 0)\r
172                 return Vector(0, 0, 0);\r
173 \r
174         return Vector(x / mag, y / mag, z / mag);\r
175 }\r
176 \r
177 double Vector::Magnitude(void)\r
178 {\r
179         return sqrt(x * x + y * y + z * z);\r
180 }\r
181 \r
182 double Vector::Angle(void)\r
183 {\r
184         // acos returns a value between zero and PI, which means we don't know which\r
185         // quadrant the angle is in... Though, if the y-coordinate of the vector is\r
186         // negative, that means that the angle is in quadrants III - IV.\r
187         double rawAngle = acos(Unit().x);\r
188         double correctedAngle = (y < 0 ? (2.0 * PI) - rawAngle : rawAngle);\r
189 \r
190         return correctedAngle;\r
191 }\r
192 \r
193 bool Vector::isZero(double epsilon/*= 1e-6*/)\r
194 {\r
195         return (fabs(x) < epsilon && fabs(y) < epsilon && fabs(z) < epsilon ? true : false);\r
196 }\r
197 \r
198 \r
199 // Class methods\r
200 \r
201 double Vector::Dot(Vector v1, Vector v2)\r
202 {\r
203         return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);\r
204 }\r
205 \r
206 double Vector::Magnitude(Vector v1, Vector v2)\r
207 {\r
208         double xx = v1.x - v2.x;\r
209         double yy = v1.y - v2.y;\r
210         double zz = v1.z - v2.z;\r
211         return sqrt(xx * xx + yy * yy + zz * zz);\r
212 }\r