]> Shamusworld >> Repos - architektonas/blob - src/vector.cpp
da0d4c557aae2fe4e68b5df17d8cf0d4ce5f0ccf
[architektonas] / src / vector.cpp
1 //\r
2 // vector.cpp: Various structures used for 3 dimensional imaging\r
3 //\r
4 // by James L. 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::operator=(Vector const v)\r
29 {\r
30         x = v.x, y = v.y, z = v.z;\r
31 \r
32         return *this;\r
33 }\r
34 \r
35 Vector Vector::operator+(Vector const v)\r
36 {\r
37         return Vector(x + v.x, y + v.y, z + v.z);\r
38 }\r
39 \r
40 Vector Vector::operator-(Vector const v)\r
41 {\r
42         return Vector(x - v.x, y - v.y, z - v.z);\r
43 }\r
44 \r
45 // Unary negation\r
46 \r
47 Vector Vector::operator-(void)\r
48 {\r
49         return Vector(-x, -y, -z);\r
50 }\r
51 \r
52 // Vector x constant\r
53 \r
54 Vector Vector::operator*(double const v)\r
55 {\r
56         return Vector(x * v, y * v, z * v);\r
57 }\r
58 \r
59 // Vector x constant\r
60 \r
61 Vector Vector::operator*(float const v)\r
62 {\r
63         return Vector(x * v, y * v, z * v);\r
64 }\r
65 \r
66 // Vector / constant\r
67 \r
68 Vector Vector::operator/(double const v)\r
69 {\r
70         return Vector(x / v, y / v, z / v);\r
71 }\r
72 \r
73 // Vector / constant\r
74 \r
75 Vector Vector::operator/(float const v)\r
76 {\r
77         return Vector(x / v, y / v, z / v);\r
78 }\r
79 \r
80 // Vector (cross) product\r
81 \r
82 Vector Vector::operator*(Vector const v)\r
83 {\r
84         // a x b = [a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1]\r
85         return Vector((y * v.z) - (z * v.y), (z * v.x) - (x * v.z), (x * v.y) - (y * v.x));\r
86 }\r
87 \r
88 // Dot product\r
89 \r
90 double Vector::Dot(Vector const v)\r
91 {\r
92         return (x * v.x) + (y * v.y) + (z * v.z);\r
93 }\r
94 \r
95 \r
96 // Vector x constant, self assigned\r
97 \r
98 Vector& Vector::operator*=(double const v)\r
99 {\r
100         x *= v, y *= v, z *= v;\r
101 \r
102         return *this;\r
103 }\r
104 \r
105 // Vector / constant, self assigned\r
106 \r
107 Vector& Vector::operator/=(double const v)\r
108 {\r
109         x /= v, y /= v, z /= v;\r
110 \r
111         return *this;\r
112 }\r
113 \r
114 // Vector + vector, self assigned\r
115 \r
116 Vector& Vector::operator+=(Vector const v)\r
117 {\r
118         x += v.x, y += v.y, z += v.z;\r
119 \r
120         return *this;\r
121 }\r
122 \r
123 // Vector + constant, self assigned\r
124 \r
125 Vector& Vector::operator+=(double const v)\r
126 {\r
127         x += v, y += v, z += v;\r
128 \r
129         return *this;\r
130 }\r
131 \r
132 \r
133 Vector Vector::Unit(void)\r
134 {\r
135         double mag = Magnitude();\r
136 \r
137         // If the magnitude of the vector is zero, then the Unit vector is undefined...\r
138         if (mag == 0)\r
139                 return Vector(0, 0, 0);\r
140 \r
141         return Vector(x / mag, y / mag, z / mag);\r
142 }\r
143 \r
144 double Vector::Magnitude(void)\r
145 {\r
146         return sqrt(x * x + y * y + z * z);\r
147 }\r
148 \r
149 double Vector::Angle(void)\r
150 {\r
151         // acos returns a value between zero and PI, which means we don't know which\r
152         // quadrant the angle is in... Though, if the y-coordinate of the vector is\r
153         // negative, that means that the angle is in quadrants III - IV.\r
154         double rawAngle = acos(Unit().x);\r
155         double correctedAngle = (y < 0 ? (2.0 * PI) - rawAngle : rawAngle);\r
156 \r
157         return correctedAngle;\r
158 }\r
159 \r
160 bool Vector::isZero(double epsilon/*= 1e-6*/)\r
161 {\r
162         return (fabs(x) < epsilon && fabs(y) < epsilon && fabs(z) < epsilon ? true : false);\r
163 }\r
164 \r
165 \r
166 // Class methods\r
167 \r
168 double Vector::Dot(Vector v1, Vector v2)\r
169 {\r
170         return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);\r
171 }\r