V-ART
point4d.cpp
Go to the documentation of this file.
1 
5 #include "vart/point4d.h"
6 #include <cmath>
7 
8 using namespace std;
9 
10 // Default "less then" comparison uses "LexicographicalLess".
12 float VART::Point4D::xWeight = 1;
13 float VART::Point4D::yWeight = 1;
14 float VART::Point4D::zWeight = 1;
15 double VART::Point4D::delta = 0.00001;
16 
18 {
19  vetCoord[0]=vetCoord[1]=vetCoord[2]=0;
20  vetCoord[3]=1;
21 }
22 
24 {
25  vetCoord[0] = point.vetCoord[0];
26  vetCoord[1] = point.vetCoord[1];
27  vetCoord[2] = point.vetCoord[2];
28  vetCoord[3] = point.vetCoord[3];
29 }
30 
31 VART::Point4D::Point4D(double x, double y, double z, double w)
32 // w = 1 (point) by default (see constructor signature)
33 {
34  SetXYZW(x, y, z, w);
35 }
36 
38 {
39  static const VART::Point4D x(1.0,0.0,0.0,0.0);
40  return x;
41 }
42 
44 {
45  static const VART::Point4D y(0.0,1.0,0.0,0.0);
46  return y;
47 }
48 
50 {
51  static const VART::Point4D z(0.0,0.0,1.0,0.0);
52  return z;
53 }
54 
56 {
57  static const VART::Point4D down(0.0,-1.0,0.0,0.0);
58  return down;
59 }
60 
62 {
63  static const VART::Point4D origin(0.0,0.0,0.0,1.0);
64  return origin;
65 }
66 
67 void VART::Point4D::SetXY(double x, double y)
68 {
69  vetCoord[0] = x;
70  vetCoord[1] = y;
71 }
72 
73 void VART::Point4D::SetXYZ(double x, double y, double z)
74 {
75  vetCoord[0] = x;
76  vetCoord[1] = y;
77  vetCoord[2] = z;
78 }
79 
80 void VART::Point4D::SetXYZW(double x, double y, double z, double w)
81 {
82  vetCoord[0] = x;
83  vetCoord[1] = y;
84  vetCoord[2] = z;
85  vetCoord[3] = w;
86 }
87 
89 // requires that x,y,z and w are not all zeros
90 {
91  if (vetCoord[3] == 0)
92  {
93  // vector normalization
94  double norma = Length();
95 
96  vetCoord[0] /= norma;
97  vetCoord[1] /= norma;
98  vetCoord[2] /= norma;
99  vetCoord[3] = 0; // this seems to avoid some round off erros
100  }
101  else
102  {
103  // point normalization
104  vetCoord[0] /= vetCoord[3];
105  vetCoord[1] /= vetCoord[3];
106  vetCoord[2] /= vetCoord[3];
107  vetCoord[3] = 1;
108  }
109 }
110 
111 double VART::Point4D::Length() const
112 {
113  return sqrt(vetCoord[0]*vetCoord[0] + vetCoord[1]*vetCoord[1] + vetCoord[2]*vetCoord[2]);
114 }
115 
117 {
118  return vetCoord[0]*p.vetCoord[0]+vetCoord[1]*p.vetCoord[1]+vetCoord[2]*p.vetCoord[2];
119 }
120 
122 {
123  return VART::Point4D(GetY()*p.GetZ()-GetZ()*p.GetY(), GetZ()*p.GetX()-GetX()*p.GetZ(), GetX()*p.GetY()-GetY()*p.GetX(), 0);
124 }
125 
126 double VART::Point4D::AngleTo(const VART::Point4D& p) const
127 // Note: This method requires both vectors to be normalized!
128 {
129  double dp = DotProduct(p);
130  // Sometimes, the Dot Product is greater then 1 due to floating point errors.
131  if (dp > 1.0)
132  return 0;
133  else
134  {
135  if (dp < -1.0)
136  return 3.1415926535897932384626433832795;
137  return acos(dp);
138  }
139 }
140 
141 double VART::Point4D::AngleTo(const Point4D& p, const Point4D& ref) const
142 // Note: This method requires all three vectors to be normalized!
143 {
144  double absoluteValue = AngleTo(p);
145  Point4D crossProduct = CrossProduct(p);
146  if (ref.AlmostEqual(crossProduct))
147  return absoluteValue;
148  else
149  return -absoluteValue;
150 }
151 
153 {
154  // Sometimes, due to floating point errors, cossine is out of [-1..1], need to check...
155  double cosValue = DotProduct(p) / (Length()*p.Length());
156  if (cosValue > 1)
157  return 0;
158  else
159  {
160  if (cosValue < -1)
161  return 3.1415926535897932384626433832795;
162  return acos(cosValue);
163  }
164 }
165 
167 {
168  // To keep the nature of the point it seems to me that the w coordinate should
169  // not be touched.
170  return VART::Point4D(-vetCoord[0], -vetCoord[1], -vetCoord[2], vetCoord[3]);
171 }
172 
174 {
175  return VART::Point4D(vetCoord[0]-point.vetCoord[0],
176  vetCoord[1]-point.vetCoord[1],
177  vetCoord[2]-point.vetCoord[2],
178  vetCoord[3]-point.vetCoord[3]);
179 }
180 
182 // This operator should not be used to sum two points. No checking is done, however,
183 // because clipping algorithms benefit from operating with vetors made from the
184 // subtraction of non-normalized points. There is no easy way to know the nature
185 // data being processed here.
186 {
187  return VART::Point4D(vetCoord[0]+vector.vetCoord[0],
188  vetCoord[1]+vector.vetCoord[1],
189  vetCoord[2]+vector.vetCoord[2],
190  vetCoord[3]+vector.vetCoord[3]);
191 }
192 
194 // Requires that the active object (a point) be normalized.
195 {
196  vetCoord[0] += vector.vetCoord[0];
197  vetCoord[1] += vector.vetCoord[1];
198  vetCoord[2] += vector.vetCoord[2];
199 }
200 
202 {
203  return VART::Point4D(vetCoord[0]*escalar,
204  vetCoord[1]*escalar,
205  vetCoord[2]*escalar,
206  vetCoord[3]*escalar);
207 }
208 
209 void VART::Point4D::operator*=(double escalar)
210 {
211  vetCoord[0]*=escalar;
212  vetCoord[1]*=escalar;
213  vetCoord[2]*=escalar;
214  vetCoord[3]*=escalar;
215 }
216 
217 bool VART::Point4D::operator==(const VART::Point4D& point) const
218 {
219  return (vetCoord[0] == point.vetCoord[0]) &&
220  (vetCoord[1] == point.vetCoord[1]) &&
221  (vetCoord[2] == point.vetCoord[2]) &&
222  (vetCoord[3] == point.vetCoord[3]);
223 }
224 
226 {
227  return (this->*operatorLess)(p);
228 }
229 
230 bool VART::Point4D::operator!=(const VART::Point4D& point) const
231 {
232  return (vetCoord[0] != point.vetCoord[0]) ||
233  (vetCoord[1] != point.vetCoord[1]) ||
234  (vetCoord[2] != point.vetCoord[2]) ||
235  (vetCoord[3] != point.vetCoord[3]);
236 }
237 
239 {
240  vetCoord[0] = point.vetCoord[0];
241  vetCoord[1] = point.vetCoord[1];
242  vetCoord[2] = point.vetCoord[2];
243  vetCoord[3] = point.vetCoord[3];
244 }
245 
247 {
248  return VART::Point4D(vetCoord[0]/escalar,
249  vetCoord[1]/escalar,
250  vetCoord[2]/escalar,
251  vetCoord[3]/escalar);
252 }
253 
255 {
256  if (vetCoord[0] == p.vetCoord[0])
257  {
258  if (vetCoord[1] == p.vetCoord[1])
259  {
260  if (vetCoord[2] == p.vetCoord[2])
261  return vetCoord[3] < p.vetCoord[3];
262  else
263  return vetCoord[2] < p.vetCoord[2];
264  }
265  else
266  return vetCoord[1] < p.vetCoord[1];
267  }
268  else
269  return vetCoord[0] < p.vetCoord[0];
270 }
271 
272 bool VART::Point4D::XThenZLess(const Point4D& p) const
273 {
274  if (vetCoord[0] == p.vetCoord[0])
275  return vetCoord[2] < p.vetCoord[2];
276  else
277  return vetCoord[0] < p.vetCoord[0];
278 }
279 
280 bool VART::Point4D::YThenXLess(const Point4D& p) const
281 {
282  if (vetCoord[1] == p.vetCoord[1])
283  return vetCoord[0] < p.vetCoord[0];
284  else
285  return vetCoord[1] < p.vetCoord[1];
286 }
287 
288 bool VART::Point4D::YThenZLess(const Point4D& p) const
289 {
290  if (vetCoord[1] == p.vetCoord[1])
291  return vetCoord[2] < p.vetCoord[2];
292  else
293  return vetCoord[1] < p.vetCoord[1];
294 }
295 
296 bool VART::Point4D::ZThenXLess(const Point4D& p) const
297 {
298  if (vetCoord[2] == p.vetCoord[2])
299  return vetCoord[0] < p.vetCoord[0];
300  else
301  return vetCoord[2] < p.vetCoord[2];
302 }
303 
304 bool VART::Point4D::ZThenYLess(const Point4D& p) const
305 {
306  if (vetCoord[2] == p.vetCoord[2])
307  return vetCoord[1] < p.vetCoord[1];
308  else
309  return vetCoord[2] < p.vetCoord[2];
310 }
311 
313 {
314  return WeightedSum() < p.WeightedSum();
315 }
316 
318 {
319  return WeightedSum() > p.WeightedSum();
320 }
321 
322 float VART::Point4D::WeightedSum() const
323 {
324  return (vetCoord[0] * xWeight) + (vetCoord[1] * yWeight) + (vetCoord[2] * zWeight);
325 }
326 
328 {
329  return abs( vetCoord[0] - v.vetCoord[0]
330  + vetCoord[1] - v.vetCoord[1]
331  + vetCoord[2] - v.vetCoord[2] ) < delta;
332 }
333 
334 namespace VART
335 {
336  ostream& operator<<(ostream& output, const Point4D& p)
337  {
338  output.setf(ios::fixed);
339  output.precision(5);
340  output << "(" << p.GetX() << "," << p.GetY() << "," << p.GetZ() << ","
341  << p.GetW() << ")";
342  output.unsetf(ios::fixed);
343  return output;
344  }
345 }
double AngleTo(const Point4D &p) const
Computes the angle up to p.
Definition: point4d.cpp:126
bool ZThenXLess(const Point4D &p) const
Definition: point4d.cpp:296
Points and vectors using homogeneous coordinates.
Definition: point4d.h:22
double Length() const
Returns the vector's length.
Definition: point4d.cpp:111
static tCompareOper operatorLess
Points to the operator to use within operator<.
Definition: point4d.h:152
static const Point4D & Y()
The Y vector (0,1,0,0).
Definition: point4d.cpp:43
Point4D operator-() const
Definition: point4d.cpp:166
void operator*=(double escalar)
Definition: point4d.cpp:209
void Normalize()
Normalizes the point/vector.
Definition: point4d.cpp:88
double GetZ() const
Definition: point4d.h:80
static float yWeight
Weight of the Y coordinate for Weighted comparisons.
Definition: point4d.h:157
Point4D operator+(const Point4D &vector) const
Addition for point and vector (or vice versa).
Definition: point4d.cpp:181
double GetY() const
Definition: point4d.h:79
static const Point4D & Z()
The Z vector (0,0,1,0).
Definition: point4d.cpp:49
bool YThenZLess(const Point4D &p) const
Definition: point4d.cpp:288
Point4D operator/(double escalar) const
Definition: point4d.cpp:246
bool LexicographicalLess(const Point4D &p) const
Verifies whether a point is less than other by looking at coordinates in lexicographical (x...
Definition: point4d.cpp:254
Point4D CrossProduct(const Point4D &p) const
Computes the cross product between "this" and "p".
Definition: point4d.cpp:121
void SetXYZ(double x, double y, double z)
Definition: point4d.cpp:73
bool WeightedLess(const Point4D &p) const
Definition: point4d.cpp:312
static float xWeight
Weight of the X coordinate for Weighted comparisons.
Definition: point4d.h:155
bool operator!=(const Point4D &point) const
Definition: point4d.cpp:230
bool operator==(const Point4D &point) const
Definition: point4d.cpp:217
bool XThenZLess(const Point4D &p) const
Verifies whether a point is less then other by looking at coordinates X, then Z only.
Definition: point4d.cpp:272
void operator=(const Point4D &point)
Definition: point4d.cpp:238
static const Point4D & X()
The X vector (1,0,0,0).
Definition: point4d.cpp:37
static float zWeight
Weight of the Z coordinate for Weighted comparisons.
Definition: point4d.h:159
static const Point4D & DOWN()
The (0,-1,0,0) vector.
Definition: point4d.cpp:55
bool operator<(const Point4D &p) const
Checks whether a point is "less then" other.
Definition: point4d.cpp:225
static double delta
Maximum difference for equality.
Definition: point4d.h:163
bool AlmostEqual(const Point4D &v) const
Check if vector is almost equal to some other vector.
Definition: point4d.cpp:327
bool ZThenYLess(const Point4D &p) const
Definition: point4d.cpp:304
static const Point4D & ORIGIN()
The (0,0,0,1) point.
Definition: point4d.cpp:61
void SetXYZW(double x, double y, double z, double w)
Definition: point4d.cpp:80
Header file for V-ART class "Point4D".
double DotProduct(const Point4D &p) const
Computes the dot product between "this" and "p".
Definition: point4d.cpp:116
ostream & operator<<(ostream &output, const Point4D &p)
Definition: point4d.cpp:336
double GetW() const
Definition: point4d.h:81
bool YThenXLess(const Point4D &p) const
Definition: point4d.cpp:280
void operator+=(const Point4D &vector)
Definition: point4d.cpp:193
Point4D operator*(double escalar) const
Definition: point4d.cpp:201
Point4D()
Creates the (0,0,0,1) point.
Definition: point4d.cpp:17
double GetX() const
Definition: point4d.h:78
void SetXY(double x, double y)
Definition: point4d.cpp:67
bool WeightedGreater(const Point4D &p) const
Definition: point4d.cpp:317
double GenericAngleTo(const Point4D &p) const
Definition: point4d.cpp:152