CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

CPoint.cpp
Go to the documentation of this file.
1 // CPoint.cpp -- n-dimensional point class implementation
2 //
3 // Copyright 2002, softSurfer (www.softsurfer.com)
4 // This code may be freely used and modified for any purpose
5 // providing that this copyright notice is included with it.
6 // SoftSurfer makes no warranty for this code, and cannot be held
7 // liable for any real or imagined damage resulting from it's use.
8 // Users of this code must verify correctness for their application.
9 //
10 // Extended by Stephen Pope -- see the CSL copyright notice
11
12 #include "CPoint.h"
13
14 using namespace csl;
15
16 // CPoint Class Methods
17
18 CPoint::CPoint(PointMode m, float tr, float ttheta) {
19 dimn=2;
20 if (m == kCartesian) {
21 x = (double)tr;
22 y = (double)ttheta;
23 z = 0;
24 } else { // else Polar
25 x = tr * cosf(ttheta);
26 y = tr * sinf(ttheta);
27 z = 0;
28 }
29 }
30
31 CPoint::CPoint(PointMode m, float tr, float ttheta, float tphi) {
32 dimn=3;
33 if (m == kCartesian) {
34 x = (double)tr;
35 y = (double)ttheta;
36 z = (double)tphi;
37 } else { // else Polar
38 x = (tr * cosf(ttheta) * cosf(tphi));
39 y = (tr * sinf(ttheta) * cosf(tphi));
40 z = (tr * sinf(tphi));
41 }
42 }
43
44 //CPoint::CPoint(CPoint & other) {
45 // dimn=other.dimn;
46 // x = other.x;
47 // y = other.y;
48 // z = other.z;
49 //}
50
51 // Assign (set) dimn
52
53 unsigned CPoint::setdim(unsigned n) {
54 dimn = n;
55 switch (n) {
56 case 1: y = 0;
57 case 2: z = 0;
58 }
59 return dimn;
60 }
61
62 void CPoint::set(PointMode m, float a, float b) {
63 dimn=2;
64 if (m == kCartesian) {
65 x = a;
66 y = b;
67 z = 0;
68 } else { // else Polar
69 x = a * cosf(b);
70 y = a * sinf(b);
71 z = 0;
72 }
73 }
74 void CPoint::set(PointMode m, float a, float b, float c) {
75 dimn=3;
76 if (m == kCartesian) {
77 x = a;
78 y = b;
79 z = c;
80 } else { // else Polar
81 x = a * cosf(b) * cosf(c);
82 y = a * sinf(b) * cosf(c);
83 z = a * sinf(c);
84 }
85 }
86
87 void CPoint::setAzimuth(double taz) {
88 float tr = this->len();
89 x=tr * cosf(taz);
90 y=tr * sinf(taz);
91 }
92
93 void CPoint::setElevation(double tele) {
94 float tr = this->len();
95 float ttheta = this->theta();
96 x=tr * cosf(ttheta) * cosf(tele);
97 y=tr * sinf(ttheta) * cosf(tele);
98 z=tr * sinf(tele);
99 }
100
101 void CPoint::setMagnitude(double tmag) {
102 float tr = tmag / this->len();
103 x *= tr;
104 y *= tr;
105 if (dimn== 3)
106 z *= tr;
107 }
108
109 //------------------------------------------------------------------
110 // Unary Ops
111 //------------------------------------------------------------------
112
113 // Unary minus
114
115 CPoint CPoint::operator-() {
116 CPoint v;
117 v.x = -x; v.y = -y; v.z = -z;
118 v.dimn = dimn;
119 return v;
120 }
121
122 // Unary 2D perp operator
123
124 CPoint CPoint::operator~() {
125 // if (dimn != 2) err = Edim; // and continue anyway
126 CPoint v;
127 v.x = -y; v.y = x; v.z = z;
128 v.dimn = dimn;
129 return v;
130 }
131
132 // Comparison (note: dimension must compare)
133
134 int CPoint::operator==(CPoint Q) {
135 if (dimn != Q.dim()) return FALSE;
136 switch (dimn) {
137 case 1:
138 return (x==Q.x);
139 case 2:
140 return (x==Q.x && y==Q.y);
141 case 3:
142 default:
143 return (x==Q.x && y==Q.y && z==Q.z);
144 }
145 }
146
147 int CPoint::operator!=(CPoint Q) {
148 if (dimn != Q.dim()) return TRUE;
149 switch (dimn) {
150 case 1:
151 return (x!=Q.x);
152 case 2:
153 return (x!=Q.x || y!=Q.y);
154 case 3:
155 default:
156 return (x!=Q.x || y!=Q.y || z!=Q.z);
157 }
158 }
159
160 // CPoint Vector Operations
161
162 CPoint CPoint::operator+(CPoint v) {
163 CPoint P;
164 P.x = x + v.x;
165 P.y = y + v.y;
166 P.z = z + v.z;
167 P.dimn = csl_max(dimn, v.dim());
168 return P;
169 }
170
171 CPoint CPoint::operator-(CPoint v) {
172 CPoint P;
173 P.x = x - v.x;
174 P.y = y - v.y;
175 P.z = z - v.z;
176 P.dimn = csl_max(dimn, v.dim());
177 return P;
178 }
179
180 //------------------------------------------------------------------
181 // Products
182 //------------------------------------------------------------------
183
184 // Inner Dot Product
185 COORD_TYPE CPoint::operator*(CPoint w ) {
186 return (x * w.x + y * w.y + z * w.z);
187 }
188
189 // 2D Exterior Perp Product
190 COORD_TYPE CPoint::operator|(CPoint w ) {
191 // if (dimn != 2) err = Edim; // and continue anyway
192 return (x * w.y - y * w.x);
193 }
194
195 // 3D Exterior Cross Product
196 CPoint CPoint::operator^(CPoint w ) {
197 CPoint v;
198 v.x = y * w.z - z * w.y;
199 v.y = z * w.x - x * w.z;
200 v.z = x * w.y - y * w.x;
201 v.dimn = 3;
202 return v;
203 }
204
205 CPoint& CPoint::operator*=(double c ) { // vector scalar mult
206 x *= c;
207 y *= c;
208 z *= c;
209 return *this;
210 }
211
212 CPoint& CPoint::operator/=(double c ) { // vector scalar div
213 x /= c;
214 y /= c;
215 z /= c;
216 return *this;
217 }
218
219 CPoint& CPoint::operator+=(CPoint v) {
220 x += v.x;
221 y += v.y;
222 z += v.z;
223 dimn = csl_max(dimn, v.dim());
224 return *this;
225 }
226
227 CPoint& CPoint::operator-=(CPoint v) {
228 x -= v.x;
229 y -= v.y;
230 z -= v.z;
231 dimn = csl_max(dimn, v.dim());
232 return *this;
233 }
234
235 CPoint& CPoint::operator^=(CPoint w ) { // 3D exterior cross product
236 double ox=x, oy=y, oz=z;
237 x = oy * w.z - oz * w.y;
238 y = oz * w.x - ox * w.z;
239 z = ox * w.y - oy * w.x;
240 dimn = 3;
241 return *this;
242 }
243
244 // CPoint Scalar Operations (convenient but often illegal)
245
246 CPoint operator*(int c, CPoint Q) {
247 CPoint P;
248 P.x = c * Q.x;
249 P.y = c * Q.y;
250 P.z = c * Q.z;
251 P.dimn = Q.dim();
252 return P;
253 }
254
255 CPoint operator*(float c, CPoint Q) {
256 CPoint P;
257 P.x = c * Q.x;
258 P.y = c * Q.y;
259 P.z = c * Q.z;
260 P.dimn = Q.dim();
261 return P;
262 }
263
264 CPoint operator*(double c, CPoint Q) {
265 CPoint P;
266 P.x = c * Q.x;
267 P.y = c * Q.y;
268 P.z = c * Q.z;
269 P.dimn = Q.dim();
270 return P;
271 }
272
273 CPoint operator*(CPoint Q, int c) {
274 CPoint P;
275 P.x = c * Q.x;
276 P.y = c * Q.y;
277 P.z = c * Q.z;
278 P.dimn = Q.dim();
279 return P;
280 }
281
282 CPoint operator*(CPoint Q, float c) {
283 CPoint P;
284 P.x = c * Q.x;
285 P.y = c * Q.y;
286 P.z = c * Q.z;
287 P.dimn = Q.dim();
288 return P;
289 }
290
291 CPoint operator*(CPoint Q, double c) {
292 CPoint P;
293 P.x = c * Q.x;
294 P.y = c * Q.y;
295 P.z = c * Q.z;
296 P.dimn = Q.dim();
297 return P;
298 }
299
300 CPoint operator/(CPoint Q, int c) {
301 CPoint P;
302 P.x = Q.x / c;
303 P.y = Q.y / c;
304 P.z = Q.z / c;
305 P.dimn = Q.dim();
306 return P;
307 }
308
309 CPoint operator/(CPoint Q, float c) {
310 CPoint P;
311 P.x = (float)(Q.x / c);
312 P.y = (float)(Q.y / c);
313 P.z = (float)(Q.z / c);
314 P.dimn = Q.dim();
315 return P;
316 }
317
318 CPoint operator/(CPoint Q, double c) {
319 CPoint P;
320 P.x = Q.x / c;
321 P.y = Q.y / c;
322 P.z = Q.z / c;
323 P.dimn = Q.dim();
324 return P;
325 }
326
327 // CPoint Addition (also convenient but often illegal)
328
329 CPoint operator+(CPoint Q, CPoint R) {
330 CPoint P;
331 P.x = Q.x + R.x;
332 P.y = Q.y + R.y;
333 P.z = Q.z + R.z;
334 P.dimn = csl_max(Q.dim(), R.dim());
335 return P;
336 }
337
338 COORD_TYPE CPoint::operator () (unsigned idx) const {
339 switch(idx) {
340 case 0:
341 return x;
342 case 1:
343 return y;
344 case 2:
345 return z;
346 default:
347 return 0;
348 }
349 }
350
351 // Distance between CPoints
352
353 COORD_TYPE CPoint::distance(CPoint * Q) { // Euclidean distance
354 COORD_TYPE dx = x - Q->x;
355 COORD_TYPE dy = y - Q->y;
356 COORD_TYPE dz = z - Q->z;
357 return sqrtf(dx*dx + dy*dy + dz*dz);
358 }
359
360 COORD_TYPE CPoint::distance2(CPoint * Q) { // squared distance (more efficient)
361 COORD_TYPE dx = x - Q->x;
362 COORD_TYPE dy = y - Q->y;
363 COORD_TYPE dz = z - Q->z;
364 return (dx*dx + dy*dy + dz*dz);
365 }
366
367 COORD_TYPE CPoint::distance(CPoint & Q) { // Euclidean distance
368 COORD_TYPE dx = x - Q.x;
369 COORD_TYPE dy = y - Q.y;
370 COORD_TYPE dz = z - Q.z;
371 return sqrtf(dx*dx + dy*dy + dz*dz);
372 }
373
374 COORD_TYPE CPoint::distance2(CPoint & Q) { // squared distance (more efficient)
375 COORD_TYPE dx = x - Q.x;
376 COORD_TYPE dy = y - Q.y;
377 COORD_TYPE dz = z - Q.z;
378 return (dx*dx + dy*dy + dz*dz);
379 }
380
381 // Polar operations -- answer the magnitude and angle of a point
382
383 COORD_TYPE CPoint::theta() {
384 if (x == 0.0) {
385 if (y >= 0.0) {
386 return CSL_PI * 0.5;
387 }
388 else {
389 return CSL_PI * 1.5;
390 }
391 }
392 COORD_TYPE tan = atanf(y / x);
393 if (x < 0)
394 return (tan + CSL_PI);
395 else if (tan < 0.0)
396 return (tan + CSL_TWOPI);
397 else
398 return (tan);
399 }
400
401 // phi = atan (sqrt (x**2 + y**2) / z)
402
403 COORD_TYPE CPoint::phi() {
404 if (z == 0.0)
405 return CSL_PI * 0.5;
406 double tan = atanf(sqrtf((x*x) + (y*y)) / z);
407 return (tan);
408 }
409
410 COORD_TYPE CPoint::ele() {
411 return asin(z / len() );
412 }
413
414 // Rotate the receiver by the argument (in radians)
415
416 void CPoint::rotateBy(double angle) {
417 COORD_TYPE mag = len();
418 COORD_TYPE t = theta() + angle;
419 x = mag * cosf(t);
420 y = mag * sinf(t);
421 }
422
423 void CPoint::normalize() { // convert to unit length
424 COORD_TYPE len = sqrt(x*x + y*y + z*z);
425 if (len == 0) return; // do nothing for nothing
426 x /= len;
427 y /= len;
428 z /= len;
429 }
430