point.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author
20  * @date
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 #pragma once
25 
26 #include <stdlib.h>
27 
28 #include <algorithm>
29 #include <cmath>
30 #include <iostream>
31 #include <limits>
32 
33 template <class Point>
34 Point
35 cross(const Point& x, const Point& y)
36 {
37  Point z;
38  z[0] = x[1] * y[2] - y[1] * x[2];
39  z[1] = x[2] * y[0] - y[2] * x[0];
40  z[2] = x[0] * y[1] - y[0] * x[1];
41  return z;
42 }
43 
44 template <class Point>
45 Point
46 sub(const Point& x, const Point& y)
47 {
48  Point z;
49  z[0] = x[0] - y[0];
50  z[1] = x[1] - y[1];
51  z[2] = x[2] - y[2];
52  return z;
53 }
54 
55 template <class Point>
56 double
57 dot(const Point& x, const Point& y)
58 {
59  return x[0] * y[0] + x[1] * y[1] + x[2] * y[2];
60 }
61 
62 template <class Point>
63 bool
64 collinear(const Point& p1, const Point& p2, const Point& p3)
65 {
66  //x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)
67  return p1[0] * (p2[1] - p3[1]) + p2[0] * (p3[1] - p1[1]) + p3[0] * (p1[1] - p2[1]) == 0;
68 }
69 
70 template <class Point>
71 bool
72 coplanar(const Point& p1, const Point& p2, const Point& p3, const Point& p4)
73 {
74  Point a = sub(p3, p1);
75  Point b = sub(p2, p1);
76  Point c = sub(p4, p3);
77 
78  Point d = cross(b, c);
79  return 0 == dot(a, d);
80 }
81 
82 template <class Point>
83 bool
84 inFront(const Point& p1, const Point& p2, const Point& p3, const Point& p4)
85 {
86  Point x = sub(p2, p1);
87  Point y = sub(p3, p1);
88  Point n = cross(x, y);
89 
90  return dot(n, sub(p4, p1)) >= 0;
91 }
92 
93 template <class Point>
94 double
95 distance(const Point& a, const Point& b)
96 {
97  return sqrt(std::pow(a[0] - b[0], 2) + std::pow(a[1] - b[1], 2) + std::pow(a[2] - b[2], 2));
98 }
99 
100 template <class Point>
101 double
102 norm(const Point& a)
103 {
104  return sqrt(std::pow(a[0], 2) + std::pow(a[1], 2) + std::pow(a[2], 2));
105 }
106 
107 template <class Point>
108 double
109 angle(const Point& a, const Point& b, const Point& c)
110 {
111  Point v1 = sub(a, b);
112  Point v2 = sub(c, b);
113  double d1 = norm(v1);
114  double d2 = norm(v2);
115  double prod = dot(v1, v2);
116 
117  return std::max(0.0, acos(prod / (d1 * d2)));
118 }
119 
120 /*
121  * Returns the distance from the point p to the line defined by xy.
122  */
123 template <class Point>
124 double
125 distanceToLine(const Point& x, const Point& y, const Point& p)
126 {
127  // d^2 = (|x - p|^2 * |y - x|^2 - ((x - p) * (y - x))^2) / |y - x|^2
128  Point px = sub(x, p);
129  Point xy = sub(y, x);
130  double nom = pow(norm(px), 2) * pow(norm(xy), 2) - pow(dot(px, xy), 2);
131  double d = nom / pow(norm(xy), 2);
132  return sqrt(d);
133 }
134 
135 inline double
136 clamp(double x, double a, double b)
137 {
138  return (x < a) ? a : ((x > b) ? b : x);
139 }
140 
141 /*
142  * Returns the distance from the point p to the CCW triangle defined by xyz.
143  */
144 template <class Point>
145 double
146 distanceToTriangle(const Point& x, const Point& y, const Point& z, const Point& p)
147 {
148  Point diff = sub(x, p);
149  Point edge0 = sub(y, x);
150  Point edge1 = sub(z, x);
151 
152  double a = dot(edge0, edge0);
153  double b = dot(edge0, edge1);
154  double c = dot(edge1, edge1);
155  double d = dot(edge0, diff);
156  double e = dot(edge1, diff);
157  double f = dot(diff, diff);
158 
159  double det = a * c - b * b;
160  double s = b * e - c * d;
161  double t = b * d - a * e;
162 
163  if (s + t < det)
164  {
165  if (s < 0.0)
166  {
167  if (t < 0.0)
168  {
169  if (d < 0.0)
170  {
171  s = clamp(-d / a, 0.0, 1.0);
172  t = 0.0;
173  }
174  else
175  {
176  s = 0.0;
177  t = clamp(-e / c, 0.0, 1.0);
178  }
179  }
180  else
181  {
182  s = 0.0;
183  t = clamp(-e / c, 0.0, 1.0);
184  }
185  }
186  else if (t < 0.0)
187  {
188  s = clamp(-d / a, 0.0, 1.0);
189  t = 0.0;
190  }
191  else
192  {
193  float invDet = 1.0 / det;
194  s *= invDet;
195  t *= invDet;
196  }
197  }
198  else
199  {
200  if (s < 0.0)
201  {
202  float tmp0 = b + d;
203  float tmp1 = c + e;
204 
205  if (tmp1 > tmp0)
206  {
207  float numer = tmp1 - tmp0;
208  float denom = a - 2 * b + c;
209  s = clamp(numer / denom, 0.0, 1.0);
210  t = 1 - s;
211  }
212  else
213  {
214  t = clamp(-e / c, 0.0, 1.0);
215  s = 0.0;
216  }
217  }
218  else if (t < 0.0)
219  {
220  if (a + d > b + e)
221  {
222  float numer = c + e - b - d;
223  float denom = a - 2 * b + c;
224  s = clamp(numer / denom, 0.0, 1.0);
225  t = 1 - s;
226  }
227  else
228  {
229  s = clamp(-e / c, 0.0, 1.0);
230  t = 0.0;
231  }
232  }
233  else
234  {
235  float numer = c + e - b - d;
236  float denom = a - 2 * b + c;
237  s = clamp(numer / denom, 0.0, 1.0);
238  t = 1.0 - s;
239  }
240  }
241 
242  double q = a * s * s + 2 * b * s * t + c * t * t + 2 * d * s + 2 * e * t + f;
243  return sqrt(q);
244 }
distanceToLine
double distanceToLine(const Point &x, const Point &y, const Point &p)
Definition: point.hpp:125
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
magic_enum::detail::n
constexpr auto n() noexcept
Definition: magic_enum.hpp:418
distanceToTriangle
double distanceToTriangle(const Point &x, const Point &y, const Point &z, const Point &p)
Definition: point.hpp:146
clamp
double clamp(double x, double a, double b)
Definition: point.hpp:136
armarx::ctrlutil::a
double a(double t, double a0, double j)
Definition: CtrlUtil.h:45
inFront
bool inFront(const Point &p1, const Point &p2, const Point &p3, const Point &p4)
Definition: point.hpp:84
Point
Definition: PointCloud.h:21
cross
Point cross(const Point &x, const Point &y)
Definition: point.hpp:35
max
T max(T t1, T t2)
Definition: gdiam.h:51
q
#define q
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:704
sub
Point sub(const Point &x, const Point &y)
Definition: point.hpp:46
collinear
bool collinear(const Point &p1, const Point &p2, const Point &p3)
Definition: point.hpp:64
dot
double dot(const Point &x, const Point &y)
Definition: point.hpp:57
angle
double angle(const Point &a, const Point &b, const Point &c)
Definition: point.hpp:109
distance
double distance(const Point &a, const Point &b)
Definition: point.hpp:95
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
coplanar
bool coplanar(const Point &p1, const Point &p2, const Point &p3, const Point &p4)
Definition: point.hpp:72
norm
double norm(const Point &a)
Definition: point.hpp:102