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
33template <class Point>
35cross(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
44template <class Point>
46sub(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
55template <class Point>
56double
57dot(const Point& x, const Point& y)
58{
59 return x[0] * y[0] + x[1] * y[1] + x[2] * y[2];
60}
61
62template <class Point>
63bool
64collinear(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
70template <class Point>
71bool
72coplanar(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
82template <class Point>
83bool
84inFront(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
93template <class Point>
94double
95distance(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
100template <class Point>
101double
102norm(const Point& a)
103{
104 return sqrt(std::pow(a[0], 2) + std::pow(a[1], 2) + std::pow(a[2], 2));
105}
106
107template <class Point>
108double
109angle(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 */
123template <class Point>
124double
125distanceToLine(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
135inline double
136clamp(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 */
144template <class Point>
145double
146distanceToTriangle(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}
constexpr T c
#define q
This file offers overloads of toIce() and fromIce() functions for STL container types.
bool collinear(const Point &p1, const Point &p2, const Point &p3)
Definition point.hpp:64
bool inFront(const Point &p1, const Point &p2, const Point &p3, const Point &p4)
Definition point.hpp:84
double clamp(double x, double a, double b)
Definition point.hpp:136
Point sub(const Point &x, const Point &y)
Definition point.hpp:46
double norm(const Point &a)
Definition point.hpp:102
double distance(const Point &a, const Point &b)
Definition point.hpp:95
double distanceToLine(const Point &x, const Point &y, const Point &p)
Definition point.hpp:125
Point cross(const Point &x, const Point &y)
Definition point.hpp:35
double angle(const Point &a, const Point &b, const Point &c)
Definition point.hpp:109
double dot(const Point &x, const Point &y)
Definition point.hpp:57
bool coplanar(const Point &p1, const Point &p2, const Point &p3, const Point &p4)
Definition point.hpp:72
double distanceToTriangle(const Point &x, const Point &y, const Point &z, const Point &p)
Definition point.hpp:146