Autoware.Auto
common_2d.hpp
Go to the documentation of this file.
1 // Copyright 2017-2019 the Autoware Foundation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Co-developed by Tier IV, Inc. and Apex.AI, Inc.
18 
19 #ifndef GEOMETRY__COMMON_2D_HPP_
20 #define GEOMETRY__COMMON_2D_HPP_
21 
22 #include <common/types.hpp>
23 #include <cmath>
24 #include <limits>
25 #include <stdexcept>
26 
27 #include "geometry/interval.hpp"
28 
31 
32 namespace autoware
33 {
34 namespace common
35 {
36 namespace geometry
37 {
38 
40 namespace point_adapter
41 {
46 template<typename PointT>
47 inline auto x_(const PointT & pt)
48 {
49  return pt.x;
50 }
55 template<typename PointT>
56 inline auto y_(const PointT & pt)
57 {
58  return pt.y;
59 }
64 template<typename PointT>
65 inline auto z_(const PointT & pt)
66 {
67  return pt.z;
68 }
73 template<typename PointT>
74 inline auto & xr_(PointT & pt)
75 {
76  return pt.x;
77 }
82 template<typename PointT>
83 inline auto & yr_(PointT & pt)
84 {
85  return pt.y;
86 }
91 template<typename PointT>
92 inline auto & zr_(PointT & pt)
93 {
94  return pt.z;
95 }
96 } // namespace point_adapter
97 
104 template<typename T1, typename T2, typename T3>
105 inline auto ccw(const T1 & pt, const T2 & q, const T3 & r)
106 {
107  using point_adapter::x_;
108  using point_adapter::y_;
109  return (((x_(q) - x_(pt)) * (y_(r) - y_(pt))) - ((y_(q) - y_(pt)) * (x_(r) - x_(pt)))) <= 0.0F;
110 }
111 
117 template<typename T1, typename T2>
118 inline auto cross_2d(const T1 & pt, const T2 & q)
119 {
120  using point_adapter::x_;
121  using point_adapter::y_;
122  return (x_(pt) * y_(q)) - (y_(pt) * x_(q));
123 }
124 
130 template<typename T1, typename T2>
131 inline auto dot_2d(const T1 & pt, const T2 & q)
132 {
133  using point_adapter::x_;
134  using point_adapter::y_;
135  return (x_(pt) * x_(q)) + (y_(pt) * y_(q));
136 }
137 
144 template<typename T>
145 T minus_2d(const T & p, const T & q)
146 {
147  T r;
148  using point_adapter::x_;
149  using point_adapter::y_;
150  point_adapter::xr_(r) = x_(p) - x_(q);
151  point_adapter::yr_(r) = y_(p) - y_(q);
152  return r;
153 }
154 
160 template<typename T>
161 T minus_2d(const T & p)
162 {
163  T r;
166  return r;
167 }
174 template<typename T>
175 T plus_2d(const T & p, const T & q)
176 {
177  T r;
178  using point_adapter::x_;
179  using point_adapter::y_;
180  point_adapter::xr_(r) = x_(p) + x_(q);
181  point_adapter::yr_(r) = y_(p) + y_(q);
182  return r;
183 }
184 
191 template<typename T>
192 T times_2d(const T & p, const float32_t a)
193 {
194  T r;
197  return r;
198 }
199 
210 template<typename T>
211 inline T intersection_2d(const T & pt, const T & u, const T & q, const T & v)
212 {
213  const float32_t num = cross_2d(minus_2d(pt, q), u);
214  float32_t den = cross_2d(v, u);
215  constexpr auto FEPS = std::numeric_limits<float32_t>::epsilon();
216  if (fabsf(den) < FEPS) {
217  if (fabsf(num) < FEPS) {
218  // collinear case, anything is ok
219  den = 1.0F;
220  } else {
221  // parallel case, no valid output
222  throw std::runtime_error(
223  "intersection_2d: no unique solution (either collinear or parallel)");
224  }
225  }
226  return plus_2d(q, times_2d(v, num / den));
227 }
228 
229 
235 template<typename T>
236 inline void rotate_2d(T & pt, const float32_t cos_th, const float32_t sin_th)
237 {
238  const float32_t x = point_adapter::x_(pt);
239  const float32_t y = point_adapter::y_(pt);
240  point_adapter::xr_(pt) = (cos_th * x) - (sin_th * y);
241  point_adapter::yr_(pt) = (sin_th * x) + (cos_th * y);
242 }
243 
249 template<typename T>
250 inline T rotate_2d(const T & pt, const float32_t th_rad)
251 {
252  T q(pt); // It's reasonable to expect a copy constructor
253  const float32_t s = sinf(th_rad);
254  const float32_t c = cosf(th_rad);
255  rotate_2d(q, c, s);
256  return q;
257 }
258 
264 template<typename T>
265 inline T get_normal(const T & pt)
266 {
267  T q(pt);
270  return q;
271 }
272 
277 template<typename T>
278 inline auto norm_2d(const T & pt)
279 {
280  return sqrtf(dot_2d(pt, pt));
281 }
282 
291 template<typename T>
292 inline T closest_segment_point_2d(const T & p, const T & q, const T & r)
293 {
294  const T qp = minus_2d(q, p);
295  const float32_t len2 = dot_2d(qp, qp);
296  T ret = p;
297  if (len2 > std::numeric_limits<float32_t>::epsilon()) {
298  const Interval_f unit_interval(0.0f, 1.0f);
299  const float32_t val = dot_2d(minus_2d(r, p), qp) / len2;
300  const float32_t t = Interval_f::clamp_to(unit_interval, val);
301  ret = plus_2d(p, times_2d(qp, t));
302  }
303  return ret;
304 }
305 //
308 // Obtained by simplifying closest_segment_point_2d.
314 // define a line
315 template<typename T>
316 inline T closest_line_point_2d(const T & p, const T & q, const T & r)
317 {
318  const T qp = minus_2d(q, p);
319  const float32_t len2 = dot_2d(qp, qp);
320  T ret = p;
321  if (len2 > std::numeric_limits<float32_t>::epsilon()) {
322  const float32_t t = dot_2d(minus_2d(r, p), qp) / len2;
323  ret = plus_2d(p, times_2d(qp, t));
324  } else {
325  throw std::runtime_error(
326  "closet_line_point_2d: line ill-defined because given points coincide");
327  }
328  return ret;
329 }
330 
337 template<typename T>
338 inline auto point_line_segment_distance_2d(const T & p, const T & q, const T & r)
339 {
340  const T pq_r = minus_2d(closest_segment_point_2d(p, q, r), r);
341  return norm_2d(pq_r);
342 }
343 
348 template<typename T>
349 inline T make_unit_vector2d(float th)
350 {
351  T r;
352  point_adapter::xr_(r) = std::cos(th);
353  point_adapter::yr_(r) = std::sin(th);
354  return r;
355 }
356 
357 } // namespace geometry
358 } // namespace common
359 } // namespace autoware
360 
361 #endif // GEOMETRY__COMMON_2D_HPP_
DifferentialEquation f
Definition: kinematic_bicycle.snippet.hpp:44
T
Definition: catr_diff.py:22
auto & zr_(PointT &pt)
Gets a reference to the z value for a point.
Definition: common_2d.hpp:92
float float32_t
Definition: types.hpp:36
DifferentialState u
Definition: kinematic_bicycle.snippet.hpp:29
T get_normal(const T &pt)
compute q s.t. p T q, or p * q = 0 This is the equivalent of a 90 degree ccw rotation ...
Definition: common_2d.hpp:265
T times_2d(const T &p, const float32_t a)
The scalar multiplication operation, p * a.
Definition: common_2d.hpp:192
bool bool8_t
Definition: types.hpp:33
This file includes common type definition.
t
Definition: catr_diff.py:22
auto & xr_(PointT &pt)
Gets a reference to the x value for a point.
Definition: common_2d.hpp:74
T plus_2d(const T &p, const T &q)
The 2d addition operation, p + q.
Definition: common_2d.hpp:175
T closest_line_point_2d(const T &p, const T &q, const T &r)
Compute the closest point on the line going through p-q to point r.
Definition: common_2d.hpp:316
T closest_segment_point_2d(const T &p, const T &q, const T &r)
Compute the closest point on line segment p-q to point r Based on equations from https://stackoverflo...
Definition: common_2d.hpp:292
auto z_(const PointT &pt)
Gets the z value for a point.
Definition: common_2d.hpp:65
a
Definition: catr_diff.py:22
Data structure to contain scalar interval bounds.
Definition: interval.hpp:52
DifferentialState x
Definition: kinematic_bicycle.snippet.hpp:28
auto norm_2d(const T &pt)
get magnitude of x and y components:
Definition: common_2d.hpp:278
auto dot_2d(const T1 &pt, const T2 &q)
compute p * q = p1 * q1 + p2 * q2
Definition: common_2d.hpp:131
auto point_line_segment_distance_2d(const T &p, const T &q, const T &r)
Compute the distance from line segment p-q to point r.
Definition: common_2d.hpp:338
DifferentialState y
Definition: kinematic_bicycle.snippet.hpp:28
auto x_(const PointT &pt)
Gets the x value for a point.
Definition: common_2d.hpp:47
void rotate_2d(T &pt, const float32_t cos_th, const float32_t sin_th)
rotate point given precomputed sin and cos
Definition: common_2d.hpp:236
T make_unit_vector2d(float th)
Make a 2D unit vector given an angle.
Definition: common_2d.hpp:349
T intersection_2d(const T &pt, const T &u, const T &q, const T &v)
solve p + t * u = q + s * v Ref: https://stackoverflow.com/questions/563198/ whats-the-most-efficent-...
Definition: common_2d.hpp:211
auto y_(const PointT &pt)
Gets the y value for a point.
Definition: common_2d.hpp:56
static T clamp_to(const Interval &i, T val)
Clamp a scalar &#39;val&#39; onto &#39;interval&#39;.
Definition: interval.hpp:345
T minus_2d(const T &p, const T &q)
Compute the 2d difference between two points, p - q.
Definition: common_2d.hpp:145
auto ccw(const T1 &pt, const T2 &q, const T3 &r)
compute whether line segment rp is counter clockwise relative to line segment qp
Definition: common_2d.hpp:105
auto & yr_(PointT &pt)
Gets a reference to the y value for a point.
Definition: common_2d.hpp:83
DifferentialState v
Definition: linear_tire.snippet.hpp:28
auto cross_2d(const T1 &pt, const T2 &q)
compute p x q = p1 * q2 - p2 * q1
Definition: common_2d.hpp:118
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24
th
Definition: catr_diff.py:22