HologramDepthmap Library
vec.cpp
Go to the documentation of this file.
1 #include "graphics/vec.h"
2 
3 namespace graphics {
4 
5 
6 const int vec2::n = 2;
7 
8 bool vec2::unit()
9 {
10  real val = norm(*this);
11 
12  if (val < epsilon) return false;
13  (*this) = (*this)/val;
14  return true;
15 }
16 
18 {
19  return norm(*this);
20 }
21 
23  // returns 1: this and other vectors are and parallel
24  // -1: this and other vectors are anti-parallel
25  // 0: this and other vectors are not parallel
26  // or at least one of the vectors is zero
27  const vec2& vv,
28  real angle_tolerance // (default=ON_DEFAULT_ANGLE_TOLERANCE) radians
29  ) const
30 {
31  int rc = 0;
32  const real ll = norm(*this) * norm(vv);
33  if ( ll > 0.0 ) {
34  const real cos_angle = (inner(*this, vv))/ll;
35  const real cos_tol = cos(angle_tolerance);
36  if ( cos_angle >= cos_tol )
37  rc = 1;
38  else if ( cos_angle <= -cos_tol )
39  rc = -1;
40  }
41  return rc;
42 }
43 
45  // returns true: this and other vectors are perpendicular
46  // false: this and other vectors are not perpendicular
47  // or at least one of the vectors is zero
48  const vec2& vv,
49  real angle_tolerance // (default=ON_DEFAULT_ANGLE_TOLERANCE) radians
50  ) const
51 {
52  bool rc = false;
53  const real ll = norm(*this)*norm(vv);
54  if ( ll > 0.0 ) {
55  if ( fabs(inner(*this, vv)/ll) <= sin(angle_tolerance) )
56  rc = true;
57  }
58  return rc;
59 }
60 
61 // set this vector to be perpendicular to another vector
62 bool vec2::perpendicular( // Result is not unitized.
63  // returns false if input vector is zero
64  const vec2& vv
65  )
66 {
67  v[1] = vv[0];
68  v[0] = -vv[1];
69  return (v[0] != 0.0 || v[1] != 0.0) ? true : false;
70 }
71 
72 // set this vector to be perpendicular to a line defined by 2 points
74  const vec2& p,
75  const vec2& q
76  )
77 {
78  return perpendicular(q-p);
79 }
80 
81 
82 void store(FILE* fp, const vec2& v)
83 {
84  fprintf(fp, "(%lg", v[0]);
85  for(int i = 1; i < 2;++i){
86  fprintf(fp, " %lg", v[i]);
87  }
88  fprintf(fp, ")\n");
89 }
90 
91 int scan(FILE* fp, const vec2& v)
92 {
93  int a = fscanf(fp, " (");
94  for(int i = 0; i < 2;++i){
95  a += fscanf(fp, " %lg", &v[i]);
96  }
97  a += fscanf(fp, " )");
98  return a;
99 }
100 
101 int apx_equal(const vec2& a, const vec2& b)
102 {
103  int c = 1;
104 
105  for (int i = 0 ; i < 2 ;++i){
106  c = c && apx_equal(a[i], b[i]);
107  }
108 
109  return c;
110 }
111 
112 int apx_equal(const vec2& a, const vec2& b, real eps)
113 {
114  int c = 1;
115 
116  for (int i = 0 ; i < 2 ;++i){
117  c = c && apx_equal(a[i], b[i], eps);
118  }
119 
120  return c;
121 }
122 
123 
124 
125 
126 const int vec3::n = 3;
127 
128 bool vec3::unit()
129 {
130  real val = norm(*this);
131 
132  if (val < epsilon) return false;
133  (*this) = (*this)/val;
134  return true;
135 }
136 
138 {
139  return norm(*this);
140 }
141 
143  // returns 1: this and other vectors are and parallel
144  // -1: this and other vectors are anti-parallel
145  // 0: this and other vectors are not parallel
146  // or at least one of the vectors is zero
147  const vec3& vv,
148  real angle_tolerance // (default=ON_DEFAULT_ANGLE_TOLERANCE) radians
149  ) const
150 {
151  int rc = 0;
152  const real ll = norm(*this) * norm(vv);
153  if ( ll > 0.0 ) {
154  const real cos_angle = (inner(*this, vv))/ll;
155  const real cos_tol = cos(angle_tolerance);
156  if ( cos_angle >= cos_tol )
157  rc = 1;
158  else if ( cos_angle <= -cos_tol )
159  rc = -1;
160  }
161  return rc;
162 }
163 
165  // returns true: this and other vectors are perpendicular
166  // false: this and other vectors are not perpendicular
167  // or at least one of the vectors is zero
168  const vec3& vv,
169  real angle_tolerance // (default=ON_DEFAULT_ANGLE_TOLERANCE) radians
170  ) const
171 {
172  bool rc = false;
173  const real ll = norm(*this) * norm(vv);
174  if ( ll > 0.0 ) {
175  if ( fabs(inner(graphics::unit(*this), graphics::unit(vv))/ll) <= sin(angle_tolerance) )
176  rc = true;
177  }
178  return rc;
179 }
180 
181 
182 bool vec3::perpendicular( const vec3& vv )
183 {
184  //bool rc = false;
185  int i, j, k;
186  real a, b;
187  k = 2;
188  if ( fabs(vv[1]) > fabs(vv[0]) ) {
189  if ( fabs(vv[2]) > fabs(vv[1]) ) {
190  i = 2;
191  j = 1;
192  k = 0;
193  a = vv[2];
194  b = -vv[1];
195  }
196  else if ( fabs(vv[2]) >= fabs(vv[0]) ){
197  i = 1;
198  j = 2;
199  k = 0;
200  a = vv[1];
201  b = -vv[2];
202  }
203  else {
204  // |vv[1]| > |vv[0]| > |vv[2]|
205  i = 1;
206  j = 0;
207  k = 2;
208  a = vv[1];
209  b = -vv[0];
210  }
211  }
212  else if ( fabs(vv[2]) > fabs(vv[0]) ) {
213  // |vv[2]| > |vv[0]| >= |vv[1]|
214  i = 2;
215  j = 0;
216  k = 1;
217  a = vv[2];
218  b = -vv[0];
219  }
220  else if ( fabs(vv[2]) > fabs(vv[1]) ) {
221  // |vv[0]| >= |vv[2]| > |vv[1]|
222  i = 0;
223  j = 2;
224  k = 1;
225  a = vv[0];
226  b = -vv[2];
227  }
228  else {
229  // |vv[0]| >= |vv[1]| >= |vv[2]|
230  i = 0;
231  j = 1;
232  k = 2;
233  a = vv[0];
234  b = -vv[1];
235  }
236 
237  v[i] = b;
238  v[j] = a;
239  v[k] = 0.0;
240  return (a != 0.0) ? true : false;
241 }
242 
243 bool
245  const vec3& P0, const vec3& P1, const vec3& P2
246  )
247 {
248  // Find a the unit normal to a triangle defined by 3 points
249  vec3 V0, V1, V2, N0, N1, N2;
250 
251  v[0] = v[1] = v[2] = 0.0;
252 
253  V0 = P2 - P1;
254  V1 = P0 - P2;
255  V2 = P1 - P0;
256 
257  N0 = cross( V1, V2 );
258 
259  if (!N0.unit())
260  return false;
261 
262  N1 = cross( V2, V0 );
263 
264  if (!N1.unit())
265  return false;
266 
267  N2 = cross( V0, V1 );
268 
269  if (!N2.unit())
270  return false;
271 
272  const real s0 = 1.0/V0.length();
273  const real s1 = 1.0/V1.length();
274  const real s2 = 1.0/V2.length();
275 
276  // choose normal with smallest total error
277  const real e0 = s0*fabs(inner(N0,V0)) + s1*fabs(inner(N0,V1)) + s2*fabs(inner(N0,V2));
278  const real e1 = s0*fabs(inner(N1,V0)) + s1*fabs(inner(N1,V1)) + s2*fabs(inner(N1,V2));
279  const real e2 = s0*fabs(inner(N2,V0)) + s1*fabs(inner(N2,V1)) + s2*fabs(inner(N2,V2));
280 
281  if ( e0 <= e1 ) {
282  if ( e0 <= e2 ) {
283  *this = N0;
284  }
285  else {
286  *this = N2;
287  }
288  }
289  else if (e1 <= e2) {
290  *this = N1;
291  }
292  else {
293  *this = N2;
294  }
295 
296  return true;
297 }
298 
299 void store(FILE* fp, const vec3& v)
300 {
301  fprintf(fp, "(%lg", v[0]);
302  for(int i = 1; i < 3;++i){
303  fprintf(fp, " %lg", v[i]);
304  }
305  fprintf(fp, ")\n");
306 }
307 
308 int scan(FILE* fp, const vec3& v)
309 {
310  int a = fscanf(fp, " (");
311  for(int i = 0; i < 3;++i){
312  a += fscanf(fp, " %lg", &v[i]);
313  }
314  a += fscanf(fp, " )");
315  return a;
316 }
317 
318 int apx_equal(const vec3& a, const vec3& b)
319 {
320  int c = 1;
321 
322  for (int i = 0 ; i < 3 ;++i){
323  c = c && apx_equal(a[i], b[i]);
324  }
325 
326  return c;
327 }
328 
329 int apx_equal(const vec3& a, const vec3& b, real eps)
330 {
331  int c = 1;
332 
333  for (int i = 0 ; i < 3 ;++i){
334  c = c && apx_equal(a[i], b[i], eps);
335  }
336 
337  return c;
338 }
339 
340 
341 
342 const int vec4::n = 4;
343 
344 bool vec4::unit()
345 {
346  real val = norm(*this);
347 
348  if (val < epsilon) return false;
349  (*this) = (*this)/val;
350  return true;
351 }
352 
354 {
355  return norm(*this);
356 }
357 
358 void store(FILE* fp, const vec4& v)
359 {
360  fprintf(fp, "(%lg", v[0]);
361  for(int i = 1; i < 4;++i){
362  fprintf(fp, " %lg", v[i]);
363  }
364  fprintf(fp, ")\n");
365 }
366 
367 int scan(FILE* fp, const vec4& v)
368 {
369  int a = fscanf(fp, " (");
370  for(int i = 0; i < 4;++i){
371  a += fscanf(fp, " %lg", &v[i]);
372  }
373  a += fscanf(fp, " )");
374  return a;
375 }
376 
377 int apx_equal(const vec4& a, const vec4& b)
378 {
379  int c = 1;
380 
381  for (int i = 0 ; i < 4 ;++i){
382  c = c && apx_equal(a[i], b[i]);
383  }
384 
385  return c;
386 }
387 
388 int apx_equal(const vec4& a, const vec4& b, real eps)
389 {
390  int c = 1;
391 
392  for (int i = 0 ; i < 4 ;++i){
393  c = c && apx_equal(a[i], b[i], eps);
394  }
395 
396  return c;
397 }
398 
399 vec3 cross(const vec3& a, const vec3& b)
400 {
401  vec3 c;
402 
403  c(0) = a(0 + 1) * b(0 + 2) - a(0 + 2) * b(0 + 1);
404 
405  c(1) = a(1 + 1) * b(1 + 2) - a(1 + 2) * b(1 + 1);
406 
407  c(2) = a(2 + 1) * b(2 + 2) - a(2 + 2) * b(2 + 1);
408 
409 
410  return c;
411 }
412 
413 }; // namespace graphics
int scan(FILE *fp, const vec2 &v)
Definition: vec.cpp:91
bool perpendicular(const vec3 &)
Definition: vec.cpp:182
real inner(const vec2 &a, const vec2 &b)
Definition: vec.h:388
real length() const
Definition: vec.cpp:137
real v[2]
Definition: vec.h:23
structure for 2-dimensional real type vector and its arithmetic.
Definition: vec.h:22
static const int n
Definition: vec.h:446
real norm(const vec2 &a)
Definition: vec.h:394
int is_parallel(const vec2 &, real=angle_tolerance) const
Definition: vec.cpp:22
vec2 unit(const vec2 &a)
Definition: vec.h:403
double real
Definition: real.h:4
static FILE * fp
Definition: sys.cpp:5
bool unit()
Definition: vec.cpp:344
int is_parallel(const vec3 &, real=angle_tolerance) const
Definition: vec.cpp:142
structure for 4-dimensional real type vector and its arithmetic.
Definition: vec.h:864
real epsilon
Definition: epsilon.cpp:7
static const int n
Definition: vec.h:866
bool is_perpendicular(const vec3 &, real=angle_tolerance) const
Definition: vec.cpp:164
vec3 cross(const vec3 &a, const vec3 &b)
Definition: vec.cpp:399
bool perpendicular(const vec2 &)
Definition: vec.cpp:62
structure for 3-dimensional real type vector and its arithmetic.
Definition: vec.h:444
int apx_equal(real x, real y)
Definition: epsilon.cpp:45
bool unit()
Definition: vec.cpp:8
static const int n
Definition: vec.h:24
real angle_tolerance
Definition: epsilon.cpp:14
void store(FILE *fp, const vec2 &v)
Definition: vec.cpp:82
real length() const
Definition: vec.cpp:353
bool unit()
Definition: vec.cpp:128
real length() const
Definition: vec.cpp:17
bool is_perpendicular(const vec2 &, real=angle_tolerance) const
Definition: vec.cpp:44