RSS.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2015, Open Source Robotics Foundation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
38 #include "coal/BV/RSS.h"
39 #include "coal/BVH/BVH_utility.h"
40 #include "coal/internal/tools.h"
41 #include "coal/collision_data.h"
42 
43 #include <iostream>
44 
45 namespace coal {
46 
49  if (val < a)
50  val = a;
51  else if (val > b)
52  val = b;
53 }
54 
67  CoalScalar A_dot_B, CoalScalar A_dot_T, CoalScalar B_dot_T) {
68  CoalScalar denom = 1 - A_dot_B * A_dot_B;
69 
70  if (denom == 0)
71  t = 0;
72  else {
73  t = (A_dot_T - B_dot_T * A_dot_B) / denom;
74  clipToRange(t, 0, a);
75  }
76 
77  u = t * A_dot_B - B_dot_T;
78  if (u < 0) {
79  u = 0;
80  t = A_dot_T;
81  clipToRange(t, 0, a);
82  } else if (u > b) {
83  u = b;
84  t = u * A_dot_B + A_dot_T;
85  clipToRange(t, 0, a);
86  }
87 }
88 
95  CoalScalar Anorm_dot_T, CoalScalar A_dot_B, CoalScalar A_dot_T,
96  CoalScalar B_dot_T) {
97  if (fabs(Anorm_dot_B) < 1e-7) return false;
98 
99  CoalScalar t, u, v;
100 
101  u = -Anorm_dot_T / Anorm_dot_B;
102  clipToRange(u, 0, b);
103 
104  t = u * A_dot_B + A_dot_T;
105  clipToRange(t, 0, a);
106 
107  v = t * A_dot_B - B_dot_T;
108 
109  if (Anorm_dot_B > 0) {
110  if (v > (u + 1e-7)) return true;
111  } else {
112  if (v < (u - 1e-7)) return true;
113  }
114  return false;
115 }
116 
120 CoalScalar rectDistance(const Matrix3s& Rab, Vec3s const& Tab,
121  const CoalScalar a[2], const CoalScalar b[2],
122  Vec3s* P = NULL, Vec3s* Q = NULL) {
123  CoalScalar A0_dot_B0, A0_dot_B1, A1_dot_B0, A1_dot_B1;
124 
125  A0_dot_B0 = Rab(0, 0);
126  A0_dot_B1 = Rab(0, 1);
127  A1_dot_B0 = Rab(1, 0);
128  A1_dot_B1 = Rab(1, 1);
129 
130  CoalScalar aA0_dot_B0, aA0_dot_B1, aA1_dot_B0, aA1_dot_B1;
131  CoalScalar bA0_dot_B0, bA0_dot_B1, bA1_dot_B0, bA1_dot_B1;
132 
133  aA0_dot_B0 = a[0] * A0_dot_B0;
134  aA0_dot_B1 = a[0] * A0_dot_B1;
135  aA1_dot_B0 = a[1] * A1_dot_B0;
136  aA1_dot_B1 = a[1] * A1_dot_B1;
137  bA0_dot_B0 = b[0] * A0_dot_B0;
138  bA1_dot_B0 = b[0] * A1_dot_B0;
139  bA0_dot_B1 = b[1] * A0_dot_B1;
140  bA1_dot_B1 = b[1] * A1_dot_B1;
141 
142  Vec3s Tba(Rab.transpose() * Tab);
143 
144  Vec3s S;
145  CoalScalar t, u;
146 
147  // determine if any edge pair contains the closest points
148 
149  CoalScalar ALL_x, ALU_x, AUL_x, AUU_x;
150  CoalScalar BLL_x, BLU_x, BUL_x, BUU_x;
151  CoalScalar LA1_lx, LA1_ux, UA1_lx, UA1_ux, LB1_lx, LB1_ux, UB1_lx, UB1_ux;
152 
153  ALL_x = -Tba[0];
154  ALU_x = ALL_x + aA1_dot_B0;
155  AUL_x = ALL_x + aA0_dot_B0;
156  AUU_x = ALU_x + aA0_dot_B0;
157 
158  if (ALL_x < ALU_x) {
159  LA1_lx = ALL_x;
160  LA1_ux = ALU_x;
161  UA1_lx = AUL_x;
162  UA1_ux = AUU_x;
163  } else {
164  LA1_lx = ALU_x;
165  LA1_ux = ALL_x;
166  UA1_lx = AUU_x;
167  UA1_ux = AUL_x;
168  }
169 
170  BLL_x = Tab[0];
171  BLU_x = BLL_x + bA0_dot_B1;
172  BUL_x = BLL_x + bA0_dot_B0;
173  BUU_x = BLU_x + bA0_dot_B0;
174 
175  if (BLL_x < BLU_x) {
176  LB1_lx = BLL_x;
177  LB1_ux = BLU_x;
178  UB1_lx = BUL_x;
179  UB1_ux = BUU_x;
180  } else {
181  LB1_lx = BLU_x;
182  LB1_ux = BLL_x;
183  UB1_lx = BUU_x;
184  UB1_ux = BUL_x;
185  }
186 
187  // UA1, UB1
188 
189  if ((UA1_ux > b[0]) && (UB1_ux > a[0])) {
190  if (((UA1_lx > b[0]) ||
191  inVoronoi(b[1], a[1], A1_dot_B0, aA0_dot_B0 - b[0] - Tba[0], A1_dot_B1,
192  aA0_dot_B1 - Tba[1], -Tab[1] - bA1_dot_B0)) &&
193  ((UB1_lx > a[0]) ||
194  inVoronoi(a[1], b[1], A0_dot_B1, Tab[0] + bA0_dot_B0 - a[0], A1_dot_B1,
195  Tab[1] + bA1_dot_B0, Tba[1] - aA0_dot_B1))) {
196  segCoords(t, u, a[1], b[1], A1_dot_B1, Tab[1] + bA1_dot_B0,
197  Tba[1] - aA0_dot_B1);
198 
199  S[0] = Tab[0] + Rab(0, 0) * b[0] + Rab(0, 1) * u - a[0];
200  S[1] = Tab[1] + Rab(1, 0) * b[0] + Rab(1, 1) * u - t;
201  S[2] = Tab[2] + Rab(2, 0) * b[0] + Rab(2, 1) * u;
202 
203  if (P && Q) {
204  *P << a[0], t, 0;
205  *Q = S + (*P);
206  }
207 
208  return S.norm();
209  }
210  }
211 
212  // UA1, LB1
213 
214  if ((UA1_lx < 0) && (LB1_ux > a[0])) {
215  if (((UA1_ux < 0) || inVoronoi(b[1], a[1], -A1_dot_B0, Tba[0] - aA0_dot_B0,
216  A1_dot_B1, aA0_dot_B1 - Tba[1], -Tab[1])) &&
217  ((LB1_lx > a[0]) ||
218  inVoronoi(a[1], b[1], A0_dot_B1, Tab[0] - a[0], A1_dot_B1, Tab[1],
219  Tba[1] - aA0_dot_B1))) {
220  segCoords(t, u, a[1], b[1], A1_dot_B1, Tab[1], Tba[1] - aA0_dot_B1);
221 
222  S[0] = Tab[0] + Rab(0, 1) * u - a[0];
223  S[1] = Tab[1] + Rab(1, 1) * u - t;
224  S[2] = Tab[2] + Rab(2, 1) * u;
225 
226  if (P && Q) {
227  *P << a[0], t, 0;
228  *Q = S + (*P);
229  }
230 
231  return S.norm();
232  }
233  }
234 
235  // LA1, UB1
236 
237  if ((LA1_ux > b[0]) && (UB1_lx < 0)) {
238  if (((LA1_lx > b[0]) ||
239  inVoronoi(b[1], a[1], A1_dot_B0, -Tba[0] - b[0], A1_dot_B1, -Tba[1],
240  -Tab[1] - bA1_dot_B0)) &&
241  ((UB1_ux < 0) || inVoronoi(a[1], b[1], -A0_dot_B1, -Tab[0] - bA0_dot_B0,
242  A1_dot_B1, Tab[1] + bA1_dot_B0, Tba[1]))) {
243  segCoords(t, u, a[1], b[1], A1_dot_B1, Tab[1] + bA1_dot_B0, Tba[1]);
244 
245  S[0] = Tab[0] + Rab(0, 0) * b[0] + Rab(0, 1) * u;
246  S[1] = Tab[1] + Rab(1, 0) * b[0] + Rab(1, 1) * u - t;
247  S[2] = Tab[2] + Rab(2, 0) * b[0] + Rab(2, 1) * u;
248 
249  if (P && Q) {
250  *P << 0, t, 0;
251  *Q = S + (*P);
252  }
253 
254  return S.norm();
255  }
256  }
257 
258  // LA1, LB1
259 
260  if ((LA1_lx < 0) && (LB1_lx < 0)) {
261  if (((LA1_ux < 0) || inVoronoi(b[1], a[1], -A1_dot_B0, Tba[0], A1_dot_B1,
262  -Tba[1], -Tab[1])) &&
263  ((LB1_ux < 0) || inVoronoi(a[1], b[1], -A0_dot_B1, -Tab[0], A1_dot_B1,
264  Tab[1], Tba[1]))) {
265  segCoords(t, u, a[1], b[1], A1_dot_B1, Tab[1], Tba[1]);
266 
267  S[0] = Tab[0] + Rab(0, 1) * u;
268  S[1] = Tab[1] + Rab(1, 1) * u - t;
269  S[2] = Tab[2] + Rab(2, 1) * u;
270 
271  if (P && Q) {
272  *P << 0, t, 0;
273  *Q = S + (*P);
274  }
275 
276  return S.norm();
277  }
278  }
279 
280  CoalScalar ALL_y, ALU_y, AUL_y, AUU_y;
281 
282  ALL_y = -Tba[1];
283  ALU_y = ALL_y + aA1_dot_B1;
284  AUL_y = ALL_y + aA0_dot_B1;
285  AUU_y = ALU_y + aA0_dot_B1;
286 
287  CoalScalar LA1_ly, LA1_uy, UA1_ly, UA1_uy, LB0_lx, LB0_ux, UB0_lx, UB0_ux;
288 
289  if (ALL_y < ALU_y) {
290  LA1_ly = ALL_y;
291  LA1_uy = ALU_y;
292  UA1_ly = AUL_y;
293  UA1_uy = AUU_y;
294  } else {
295  LA1_ly = ALU_y;
296  LA1_uy = ALL_y;
297  UA1_ly = AUU_y;
298  UA1_uy = AUL_y;
299  }
300 
301  if (BLL_x < BUL_x) {
302  LB0_lx = BLL_x;
303  LB0_ux = BUL_x;
304  UB0_lx = BLU_x;
305  UB0_ux = BUU_x;
306  } else {
307  LB0_lx = BUL_x;
308  LB0_ux = BLL_x;
309  UB0_lx = BUU_x;
310  UB0_ux = BLU_x;
311  }
312 
313  // UA1, UB0
314 
315  if ((UA1_uy > b[1]) && (UB0_ux > a[0])) {
316  if (((UA1_ly > b[1]) ||
317  inVoronoi(b[0], a[1], A1_dot_B1, aA0_dot_B1 - Tba[1] - b[1], A1_dot_B0,
318  aA0_dot_B0 - Tba[0], -Tab[1] - bA1_dot_B1)) &&
319  ((UB0_lx > a[0]) ||
320  inVoronoi(a[1], b[0], A0_dot_B0, Tab[0] - a[0] + bA0_dot_B1, A1_dot_B0,
321  Tab[1] + bA1_dot_B1, Tba[0] - aA0_dot_B0))) {
322  segCoords(t, u, a[1], b[0], A1_dot_B0, Tab[1] + bA1_dot_B1,
323  Tba[0] - aA0_dot_B0);
324 
325  S[0] = Tab[0] + Rab(0, 1) * b[1] + Rab(0, 0) * u - a[0];
326  S[1] = Tab[1] + Rab(1, 1) * b[1] + Rab(1, 0) * u - t;
327  S[2] = Tab[2] + Rab(2, 1) * b[1] + Rab(2, 0) * u;
328 
329  if (P && Q) {
330  *P << a[0], t, 0;
331  *Q = S + (*P);
332  }
333 
334  return S.norm();
335  }
336  }
337 
338  // UA1, LB0
339 
340  if ((UA1_ly < 0) && (LB0_ux > a[0])) {
341  if (((UA1_uy < 0) || inVoronoi(b[0], a[1], -A1_dot_B1, Tba[1] - aA0_dot_B1,
342  A1_dot_B0, aA0_dot_B0 - Tba[0], -Tab[1])) &&
343  ((LB0_lx > a[0]) ||
344  inVoronoi(a[1], b[0], A0_dot_B0, Tab[0] - a[0], A1_dot_B0, Tab[1],
345  Tba[0] - aA0_dot_B0))) {
346  segCoords(t, u, a[1], b[0], A1_dot_B0, Tab[1], Tba[0] - aA0_dot_B0);
347 
348  S[0] = Tab[0] + Rab(0, 0) * u - a[0];
349  S[1] = Tab[1] + Rab(1, 0) * u - t;
350  S[2] = Tab[2] + Rab(2, 0) * u;
351 
352  if (P && Q) {
353  *P << a[0], t, 0;
354  *Q = S + (*P);
355  }
356 
357  return S.norm();
358  }
359  }
360 
361  // LA1, UB0
362 
363  if ((LA1_uy > b[1]) && (UB0_lx < 0)) {
364  if (((LA1_ly > b[1]) ||
365  inVoronoi(b[0], a[1], A1_dot_B1, -Tba[1] - b[1], A1_dot_B0, -Tba[0],
366  -Tab[1] - bA1_dot_B1)) &&
367 
368  ((UB0_ux < 0) || inVoronoi(a[1], b[0], -A0_dot_B0, -Tab[0] - bA0_dot_B1,
369  A1_dot_B0, Tab[1] + bA1_dot_B1, Tba[0]))) {
370  segCoords(t, u, a[1], b[0], A1_dot_B0, Tab[1] + bA1_dot_B1, Tba[0]);
371 
372  S[0] = Tab[0] + Rab(0, 1) * b[1] + Rab(0, 0) * u;
373  S[1] = Tab[1] + Rab(1, 1) * b[1] + Rab(1, 0) * u - t;
374  S[2] = Tab[2] + Rab(2, 1) * b[1] + Rab(2, 0) * u;
375 
376  if (P && Q) {
377  *P << 0, t, 0;
378  *Q = S + (*P);
379  }
380 
381  return S.norm();
382  }
383  }
384 
385  // LA1, LB0
386 
387  if ((LA1_ly < 0) && (LB0_lx < 0)) {
388  if (((LA1_uy < 0) || inVoronoi(b[0], a[1], -A1_dot_B1, Tba[1], A1_dot_B0,
389  -Tba[0], -Tab[1])) &&
390  ((LB0_ux < 0) || inVoronoi(a[1], b[0], -A0_dot_B0, -Tab[0], A1_dot_B0,
391  Tab[1], Tba[0]))) {
392  segCoords(t, u, a[1], b[0], A1_dot_B0, Tab[1], Tba[0]);
393 
394  S[0] = Tab[0] + Rab(0, 0) * u;
395  S[1] = Tab[1] + Rab(1, 0) * u - t;
396  S[2] = Tab[2] + Rab(2, 0) * u;
397 
398  if (P && Q) {
399  *P << 0, t, 0;
400  *Q = S + (*P);
401  }
402 
403  return S.norm();
404  }
405  }
406 
407  CoalScalar BLL_y, BLU_y, BUL_y, BUU_y;
408 
409  BLL_y = Tab[1];
410  BLU_y = BLL_y + bA1_dot_B1;
411  BUL_y = BLL_y + bA1_dot_B0;
412  BUU_y = BLU_y + bA1_dot_B0;
413 
414  CoalScalar LA0_lx, LA0_ux, UA0_lx, UA0_ux, LB1_ly, LB1_uy, UB1_ly, UB1_uy;
415 
416  if (ALL_x < AUL_x) {
417  LA0_lx = ALL_x;
418  LA0_ux = AUL_x;
419  UA0_lx = ALU_x;
420  UA0_ux = AUU_x;
421  } else {
422  LA0_lx = AUL_x;
423  LA0_ux = ALL_x;
424  UA0_lx = AUU_x;
425  UA0_ux = ALU_x;
426  }
427 
428  if (BLL_y < BLU_y) {
429  LB1_ly = BLL_y;
430  LB1_uy = BLU_y;
431  UB1_ly = BUL_y;
432  UB1_uy = BUU_y;
433  } else {
434  LB1_ly = BLU_y;
435  LB1_uy = BLL_y;
436  UB1_ly = BUU_y;
437  UB1_uy = BUL_y;
438  }
439 
440  // UA0, UB1
441 
442  if ((UA0_ux > b[0]) && (UB1_uy > a[1])) {
443  if (((UA0_lx > b[0]) ||
444  inVoronoi(b[1], a[0], A0_dot_B0, aA1_dot_B0 - Tba[0] - b[0], A0_dot_B1,
445  aA1_dot_B1 - Tba[1], -Tab[0] - bA0_dot_B0)) &&
446  ((UB1_ly > a[1]) ||
447  inVoronoi(a[0], b[1], A1_dot_B1, Tab[1] - a[1] + bA1_dot_B0, A0_dot_B1,
448  Tab[0] + bA0_dot_B0, Tba[1] - aA1_dot_B1))) {
449  segCoords(t, u, a[0], b[1], A0_dot_B1, Tab[0] + bA0_dot_B0,
450  Tba[1] - aA1_dot_B1);
451 
452  S[0] = Tab[0] + Rab(0, 0) * b[0] + Rab(0, 1) * u - t;
453  S[1] = Tab[1] + Rab(1, 0) * b[0] + Rab(1, 1) * u - a[1];
454  S[2] = Tab[2] + Rab(2, 0) * b[0] + Rab(2, 1) * u;
455 
456  if (P && Q) {
457  *P << t, a[1], 0;
458  *Q = S + (*P);
459  }
460 
461  return S.norm();
462  }
463  }
464 
465  // UA0, LB1
466 
467  if ((UA0_lx < 0) && (LB1_uy > a[1])) {
468  if (((UA0_ux < 0) || inVoronoi(b[1], a[0], -A0_dot_B0, Tba[0] - aA1_dot_B0,
469  A0_dot_B1, aA1_dot_B1 - Tba[1], -Tab[0])) &&
470  ((LB1_ly > a[1]) ||
471  inVoronoi(a[0], b[1], A1_dot_B1, Tab[1] - a[1], A0_dot_B1, Tab[0],
472  Tba[1] - aA1_dot_B1))) {
473  segCoords(t, u, a[0], b[1], A0_dot_B1, Tab[0], Tba[1] - aA1_dot_B1);
474 
475  S[0] = Tab[0] + Rab(0, 1) * u - t;
476  S[1] = Tab[1] + Rab(1, 1) * u - a[1];
477  S[2] = Tab[2] + Rab(2, 1) * u;
478 
479  if (P && Q) {
480  *P << t, a[1], 0;
481  *Q = S + (*P);
482  }
483 
484  return S.norm();
485  }
486  }
487 
488  // LA0, UB1
489 
490  if ((LA0_ux > b[0]) && (UB1_ly < 0)) {
491  if (((LA0_lx > b[0]) ||
492  inVoronoi(b[1], a[0], A0_dot_B0, -b[0] - Tba[0], A0_dot_B1, -Tba[1],
493  -bA0_dot_B0 - Tab[0])) &&
494  ((UB1_uy < 0) || inVoronoi(a[0], b[1], -A1_dot_B1, -Tab[1] - bA1_dot_B0,
495  A0_dot_B1, Tab[0] + bA0_dot_B0, Tba[1]))) {
496  segCoords(t, u, a[0], b[1], A0_dot_B1, Tab[0] + bA0_dot_B0, Tba[1]);
497 
498  S[0] = Tab[0] + Rab(0, 0) * b[0] + Rab(0, 1) * u - t;
499  S[1] = Tab[1] + Rab(1, 0) * b[0] + Rab(1, 1) * u;
500  S[2] = Tab[2] + Rab(2, 0) * b[0] + Rab(2, 1) * u;
501 
502  if (P && Q) {
503  *P << t, 0, 0;
504  *Q = S + (*P);
505  }
506 
507  return S.norm();
508  }
509  }
510 
511  // LA0, LB1
512 
513  if ((LA0_lx < 0) && (LB1_ly < 0)) {
514  if (((LA0_ux < 0) || inVoronoi(b[1], a[0], -A0_dot_B0, Tba[0], A0_dot_B1,
515  -Tba[1], -Tab[0])) &&
516  ((LB1_uy < 0) || inVoronoi(a[0], b[1], -A1_dot_B1, -Tab[1], A0_dot_B1,
517  Tab[0], Tba[1]))) {
518  segCoords(t, u, a[0], b[1], A0_dot_B1, Tab[0], Tba[1]);
519 
520  S[0] = Tab[0] + Rab(0, 1) * u - t;
521  S[1] = Tab[1] + Rab(1, 1) * u;
522  S[2] = Tab[2] + Rab(2, 1) * u;
523 
524  if (P && Q) {
525  *P << t, 0, 0;
526  *Q = S + (*P);
527  }
528 
529  return S.norm();
530  }
531  }
532 
533  CoalScalar LA0_ly, LA0_uy, UA0_ly, UA0_uy, LB0_ly, LB0_uy, UB0_ly, UB0_uy;
534 
535  if (ALL_y < AUL_y) {
536  LA0_ly = ALL_y;
537  LA0_uy = AUL_y;
538  UA0_ly = ALU_y;
539  UA0_uy = AUU_y;
540  } else {
541  LA0_ly = AUL_y;
542  LA0_uy = ALL_y;
543  UA0_ly = AUU_y;
544  UA0_uy = ALU_y;
545  }
546 
547  if (BLL_y < BUL_y) {
548  LB0_ly = BLL_y;
549  LB0_uy = BUL_y;
550  UB0_ly = BLU_y;
551  UB0_uy = BUU_y;
552  } else {
553  LB0_ly = BUL_y;
554  LB0_uy = BLL_y;
555  UB0_ly = BUU_y;
556  UB0_uy = BLU_y;
557  }
558 
559  // UA0, UB0
560 
561  if ((UA0_uy > b[1]) && (UB0_uy > a[1])) {
562  if (((UA0_ly > b[1]) ||
563  inVoronoi(b[0], a[0], A0_dot_B1, aA1_dot_B1 - Tba[1] - b[1], A0_dot_B0,
564  aA1_dot_B0 - Tba[0], -Tab[0] - bA0_dot_B1)) &&
565  ((UB0_ly > a[1]) ||
566  inVoronoi(a[0], b[0], A1_dot_B0, Tab[1] - a[1] + bA1_dot_B1, A0_dot_B0,
567  Tab[0] + bA0_dot_B1, Tba[0] - aA1_dot_B0))) {
568  segCoords(t, u, a[0], b[0], A0_dot_B0, Tab[0] + bA0_dot_B1,
569  Tba[0] - aA1_dot_B0);
570 
571  S[0] = Tab[0] + Rab(0, 1) * b[1] + Rab(0, 0) * u - t;
572  S[1] = Tab[1] + Rab(1, 1) * b[1] + Rab(1, 0) * u - a[1];
573  S[2] = Tab[2] + Rab(2, 1) * b[1] + Rab(2, 0) * u;
574 
575  if (P && Q) {
576  *P << t, a[1], 0;
577  *Q = S + (*P);
578  }
579 
580  return S.norm();
581  }
582  }
583 
584  // UA0, LB0
585 
586  if ((UA0_ly < 0) && (LB0_uy > a[1])) {
587  if (((UA0_uy < 0) || inVoronoi(b[0], a[0], -A0_dot_B1, Tba[1] - aA1_dot_B1,
588  A0_dot_B0, aA1_dot_B0 - Tba[0], -Tab[0])) &&
589  ((LB0_ly > a[1]) ||
590  inVoronoi(a[0], b[0], A1_dot_B0, Tab[1] - a[1], A0_dot_B0, Tab[0],
591  Tba[0] - aA1_dot_B0))) {
592  segCoords(t, u, a[0], b[0], A0_dot_B0, Tab[0], Tba[0] - aA1_dot_B0);
593 
594  S[0] = Tab[0] + Rab(0, 0) * u - t;
595  S[1] = Tab[1] + Rab(1, 0) * u - a[1];
596  S[2] = Tab[2] + Rab(2, 0) * u;
597 
598  if (P && Q) {
599  *P << t, a[1], 0;
600  *Q = S + (*P);
601  }
602 
603  return S.norm();
604  }
605  }
606 
607  // LA0, UB0
608 
609  if ((LA0_uy > b[1]) && (UB0_ly < 0)) {
610  if (((LA0_ly > b[1]) ||
611  inVoronoi(b[0], a[0], A0_dot_B1, -Tba[1] - b[1], A0_dot_B0, -Tba[0],
612  -Tab[0] - bA0_dot_B1)) &&
613 
614  ((UB0_uy < 0) || inVoronoi(a[0], b[0], -A1_dot_B0, -Tab[1] - bA1_dot_B1,
615  A0_dot_B0, Tab[0] + bA0_dot_B1, Tba[0]))) {
616  segCoords(t, u, a[0], b[0], A0_dot_B0, Tab[0] + bA0_dot_B1, Tba[0]);
617 
618  S[0] = Tab[0] + Rab(0, 1) * b[1] + Rab(0, 0) * u - t;
619  S[1] = Tab[1] + Rab(1, 1) * b[1] + Rab(1, 0) * u;
620  S[2] = Tab[2] + Rab(2, 1) * b[1] + Rab(2, 0) * u;
621 
622  if (P && Q) {
623  *P << t, 0, 0;
624  *Q = S + (*P);
625  }
626 
627  return S.norm();
628  }
629  }
630 
631  // LA0, LB0
632 
633  if ((LA0_ly < 0) && (LB0_ly < 0)) {
634  if (((LA0_uy < 0) || inVoronoi(b[0], a[0], -A0_dot_B1, Tba[1], A0_dot_B0,
635  -Tba[0], -Tab[0])) &&
636  ((LB0_uy < 0) || inVoronoi(a[0], b[0], -A1_dot_B0, -Tab[1], A0_dot_B0,
637  Tab[0], Tba[0]))) {
638  segCoords(t, u, a[0], b[0], A0_dot_B0, Tab[0], Tba[0]);
639 
640  S[0] = Tab[0] + Rab(0, 0) * u - t;
641  S[1] = Tab[1] + Rab(1, 0) * u;
642  S[2] = Tab[2] + Rab(2, 0) * u;
643 
644  if (P && Q) {
645  *P << t, 0, 0;
646  *Q = S + (*P);
647  }
648 
649  return S.norm();
650  }
651  }
652 
653  // no edges passed, take max separation along face normals
654 
655  CoalScalar sep1, sep2;
656 
657  if (Tab[2] > 0.0) {
658  sep1 = Tab[2];
659  if (Rab(2, 0) < 0.0) sep1 += b[0] * Rab(2, 0);
660  if (Rab(2, 1) < 0.0) sep1 += b[1] * Rab(2, 1);
661  } else {
662  sep1 = -Tab[2];
663  if (Rab(2, 0) > 0.0) sep1 -= b[0] * Rab(2, 0);
664  if (Rab(2, 1) > 0.0) sep1 -= b[1] * Rab(2, 1);
665  }
666 
667  if (Tba[2] < 0) {
668  sep2 = -Tba[2];
669  if (Rab(0, 2) < 0.0) sep2 += a[0] * Rab(0, 2);
670  if (Rab(1, 2) < 0.0) sep2 += a[1] * Rab(1, 2);
671  } else {
672  sep2 = Tba[2];
673  if (Rab(0, 2) > 0.0) sep2 -= a[0] * Rab(0, 2);
674  if (Rab(1, 2) > 0.0) sep2 -= a[1] * Rab(1, 2);
675  }
676 
677  if (sep1 >= sep2 && sep1 >= 0) {
678  if (Tab[2] > 0)
679  S << 0, 0, sep1;
680  else
681  S << 0, 0, -sep1;
682 
683  if (P && Q) {
684  *Q = S;
685  P->setZero();
686  }
687  }
688 
689  if (sep2 >= sep1 && sep2 >= 0) {
690  Vec3s Q_(Tab[0], Tab[1], Tab[2]);
691  Vec3s P_;
692  if (Tba[2] < 0) {
693  P_[0] = Rab(0, 2) * sep2 + Tab[0];
694  P_[1] = Rab(1, 2) * sep2 + Tab[1];
695  P_[2] = Rab(2, 2) * sep2 + Tab[2];
696  } else {
697  P_[0] = -Rab(0, 2) * sep2 + Tab[0];
698  P_[1] = -Rab(1, 2) * sep2 + Tab[1];
699  P_[2] = -Rab(2, 2) * sep2 + Tab[2];
700  }
701 
702  S = Q_ - P_;
703 
704  if (P && Q) {
705  *P = P_;
706  *Q = Q_;
707  }
708  }
709 
710  CoalScalar sep = (sep1 > sep2 ? sep1 : sep2);
711  return (sep > 0 ? sep : 0);
712 }
713 
714 bool RSS::overlap(const RSS& other) const {
718 
720  Vec3s T(axes.transpose() * (other.Tr - Tr));
721 
723  Matrix3s R(axes.transpose() * other.axes);
724 
725  CoalScalar dist = rectDistance(R, T, length, other.length);
726  return (dist <= (radius + other.radius));
727 }
728 
729 bool overlap(const Matrix3s& R0, const Vec3s& T0, const RSS& b1,
730  const RSS& b2) {
731  // ROb2 = R0 . b2
732  // where b2 = [ b2.axis [0] | b2.axis [1] | b2.axis [2] ]
733 
734  // (1 0 0)^T R0b2^T axis [0] = (1 0 0)^T b2^T R0^T axis [0]
735  // R = b2^T RO^T b1
736  Vec3s Ttemp(R0.transpose() * (b2.Tr - T0) - b1.Tr);
737  Vec3s T(b1.axes.transpose() * Ttemp);
738  Matrix3s R(b1.axes.transpose() * R0.transpose() * b2.axes);
739 
740  CoalScalar dist = rectDistance(R, T, b1.length, b2.length);
741  return (dist <= (b1.radius + b2.radius));
742 }
743 
744 bool overlap(const Matrix3s& R0, const Vec3s& T0, const RSS& b1, const RSS& b2,
745  const CollisionRequest& request, CoalScalar& sqrDistLowerBound) {
746  // ROb2 = R0 . b2
747  // where b2 = [ b2.axis [0] | b2.axis [1] | b2.axis [2] ]
748 
749  // (1 0 0)^T R0b2^T axis [0] = (1 0 0)^T b2^T R0^T axis [0]
750  // R = b2^T RO^T b1
751  Vec3s Ttemp(R0.transpose() * (b2.Tr - T0) - b1.Tr);
752  Vec3s T(b1.axes.transpose() * Ttemp);
753  Matrix3s R(b1.axes.transpose() * R0.transpose() * b2.axes);
754 
755  CoalScalar dist = rectDistance(R, T, b1.length, b2.length) - b1.radius -
756  b2.radius - request.security_margin;
757  if (dist <= 0) return true;
758  sqrDistLowerBound = dist * dist;
759  return false;
760 }
761 
762 bool RSS::contain(const Vec3s& p) const {
763  Vec3s local_p = p - Tr;
764  // FIXME: Vec3s proj (axes.transpose() * local_p);
765  CoalScalar proj0 = local_p.dot(axes.col(0));
766  CoalScalar proj1 = local_p.dot(axes.col(1));
767  CoalScalar proj2 = local_p.dot(axes.col(2));
768  CoalScalar abs_proj2 = fabs(proj2);
769  Vec3s proj(proj0, proj1, proj2);
770 
772  if ((proj0 < length[0]) && (proj0 > 0) && (proj1 < length[1]) &&
773  (proj1 > 0)) {
774  return (abs_proj2 < radius);
775  } else if ((proj0 < length[0]) && (proj0 > 0) &&
776  ((proj1 < 0) || (proj1 > length[1]))) {
777  CoalScalar y = (proj1 > 0) ? length[1] : 0;
778  Vec3s v(proj0, y, 0);
779  return ((proj - v).squaredNorm() < radius * radius);
780  } else if ((proj1 < length[1]) && (proj1 > 0) &&
781  ((proj0 < 0) || (proj0 > length[0]))) {
782  CoalScalar x = (proj0 > 0) ? length[0] : 0;
783  Vec3s v(x, proj1, 0);
784  return ((proj - v).squaredNorm() < radius * radius);
785  } else {
786  CoalScalar x = (proj0 > 0) ? length[0] : 0;
787  CoalScalar y = (proj1 > 0) ? length[1] : 0;
788  Vec3s v(x, y, 0);
789  return ((proj - v).squaredNorm() < radius * radius);
790  }
791 }
792 
794  Vec3s local_p = p - Tr;
795  CoalScalar proj0 = local_p.dot(axes.col(0));
796  CoalScalar proj1 = local_p.dot(axes.col(1));
797  CoalScalar proj2 = local_p.dot(axes.col(2));
798  CoalScalar abs_proj2 = fabs(proj2);
799  Vec3s proj(proj0, proj1, proj2);
800 
801  // projection is within the rectangle
802  if ((proj0 < length[0]) && (proj0 > 0) && (proj1 < length[1]) &&
803  (proj1 > 0)) {
804  if (abs_proj2 < radius)
805  ; // do nothing
806  else {
807  radius = 0.5 * (radius + abs_proj2); // enlarge the r
808  // change RSS origin position
809  if (proj2 > 0)
810  Tr[2] += 0.5 * (abs_proj2 - radius);
811  else
812  Tr[2] -= 0.5 * (abs_proj2 - radius);
813  }
814  } else if ((proj0 < length[0]) && (proj0 > 0) &&
815  ((proj1 < 0) || (proj1 > length[1]))) {
816  CoalScalar y = (proj1 > 0) ? length[1] : 0;
817  Vec3s v(proj0, y, 0);
818  CoalScalar new_r_sqr = (proj - v).squaredNorm();
819  if (new_r_sqr < radius * radius)
820  ; // do nothing
821  else {
822  if (abs_proj2 < radius) {
823  CoalScalar delta_y =
824  -std::sqrt(radius * radius - proj2 * proj2) + fabs(proj1 - y);
825  length[1] += delta_y;
826  if (proj1 < 0) Tr[1] -= delta_y;
827  } else {
828  CoalScalar delta_y = fabs(proj1 - y);
829  length[1] += delta_y;
830  if (proj1 < 0) Tr[1] -= delta_y;
831 
832  if (proj2 > 0)
833  Tr[2] += 0.5 * (abs_proj2 - radius);
834  else
835  Tr[2] -= 0.5 * (abs_proj2 - radius);
836  }
837  }
838  } else if ((proj1 < length[1]) && (proj1 > 0) &&
839  ((proj0 < 0) || (proj0 > length[0]))) {
840  CoalScalar x = (proj0 > 0) ? length[0] : 0;
841  Vec3s v(x, proj1, 0);
842  CoalScalar new_r_sqr = (proj - v).squaredNorm();
843  if (new_r_sqr < radius * radius)
844  ; // do nothing
845  else {
846  if (abs_proj2 < radius) {
847  CoalScalar delta_x =
848  -std::sqrt(radius * radius - proj2 * proj2) + fabs(proj0 - x);
849  length[0] += delta_x;
850  if (proj0 < 0) Tr[0] -= delta_x;
851  } else {
852  CoalScalar delta_x = fabs(proj0 - x);
853  length[0] += delta_x;
854  if (proj0 < 0) Tr[0] -= delta_x;
855 
856  if (proj2 > 0)
857  Tr[2] += 0.5 * (abs_proj2 - radius);
858  else
859  Tr[2] -= 0.5 * (abs_proj2 - radius);
860  }
861  }
862  } else {
863  CoalScalar x = (proj0 > 0) ? length[0] : 0;
864  CoalScalar y = (proj1 > 0) ? length[1] : 0;
865  Vec3s v(x, y, 0);
866  CoalScalar new_r_sqr = (proj - v).squaredNorm();
867  if (new_r_sqr < radius * radius)
868  ; // do nothing
869  else {
870  if (abs_proj2 < radius) {
871  CoalScalar diag = std::sqrt(new_r_sqr - proj2 * proj2);
872  CoalScalar delta_diag =
873  -std::sqrt(radius * radius - proj2 * proj2) + diag;
874 
875  CoalScalar delta_x = delta_diag / diag * fabs(proj0 - x);
876  CoalScalar delta_y = delta_diag / diag * fabs(proj1 - y);
877  length[0] += delta_x;
878  length[1] += delta_y;
879 
880  if (proj0 < 0 && proj1 < 0) {
881  Tr[0] -= delta_x;
882  Tr[1] -= delta_y;
883  }
884  } else {
885  CoalScalar delta_x = fabs(proj0 - x);
886  CoalScalar delta_y = fabs(proj1 - y);
887 
888  length[0] += delta_x;
889  length[1] += delta_y;
890 
891  if (proj0 < 0 && proj1 < 0) {
892  Tr[0] -= delta_x;
893  Tr[1] -= delta_y;
894  }
895 
896  if (proj2 > 0)
897  Tr[2] += 0.5 * (abs_proj2 - radius);
898  else
899  Tr[2] -= 0.5 * (abs_proj2 - radius);
900  }
901  }
902  }
903 
904  return *this;
905 }
906 
907 RSS RSS::operator+(const RSS& other) const {
908  RSS bv;
909 
910  Vec3s v[16];
911  Vec3s d0_pos(other.axes.col(0) * (other.length[0] + other.radius));
912  Vec3s d1_pos(other.axes.col(1) * (other.length[1] + other.radius));
913  Vec3s d0_neg(other.axes.col(0) * (-other.radius));
914  Vec3s d1_neg(other.axes.col(1) * (-other.radius));
915  Vec3s d2_pos(other.axes.col(2) * other.radius);
916  Vec3s d2_neg(other.axes.col(2) * (-other.radius));
917 
918  v[0].noalias() = other.Tr + d0_pos + d1_pos + d2_pos;
919  v[1].noalias() = other.Tr + d0_pos + d1_pos + d2_neg;
920  v[2].noalias() = other.Tr + d0_pos + d1_neg + d2_pos;
921  v[3].noalias() = other.Tr + d0_pos + d1_neg + d2_neg;
922  v[4].noalias() = other.Tr + d0_neg + d1_pos + d2_pos;
923  v[5].noalias() = other.Tr + d0_neg + d1_pos + d2_neg;
924  v[6].noalias() = other.Tr + d0_neg + d1_neg + d2_pos;
925  v[7].noalias() = other.Tr + d0_neg + d1_neg + d2_neg;
926 
927  d0_pos.noalias() = axes.col(0) * (length[0] + radius);
928  d1_pos.noalias() = axes.col(1) * (length[1] + radius);
929  d0_neg.noalias() = axes.col(0) * (-radius);
930  d1_neg.noalias() = axes.col(1) * (-radius);
931  d2_pos.noalias() = axes.col(2) * radius;
932  d2_neg.noalias() = axes.col(2) * (-radius);
933 
934  v[8].noalias() = Tr + d0_pos + d1_pos + d2_pos;
935  v[9].noalias() = Tr + d0_pos + d1_pos + d2_neg;
936  v[10].noalias() = Tr + d0_pos + d1_neg + d2_pos;
937  v[11].noalias() = Tr + d0_pos + d1_neg + d2_neg;
938  v[12].noalias() = Tr + d0_neg + d1_pos + d2_pos;
939  v[13].noalias() = Tr + d0_neg + d1_pos + d2_neg;
940  v[14].noalias() = Tr + d0_neg + d1_neg + d2_pos;
941  v[15].noalias() = Tr + d0_neg + d1_neg + d2_neg;
942 
943  Matrix3s M; // row first matrix
944  Vec3s E[3]; // row first eigen-vectors
945  CoalScalar s[3] = {0, 0, 0};
946 
947  getCovariance(v, NULL, NULL, NULL, 16, M);
948  eigen(M, s, E);
949 
950  int min, mid, max;
951  if (s[0] > s[1]) {
952  max = 0;
953  min = 1;
954  } else {
955  min = 0;
956  max = 1;
957  }
958  if (s[2] < s[min]) {
959  mid = min;
960  min = 2;
961  } else if (s[2] > s[max]) {
962  mid = max;
963  max = 2;
964  } else {
965  mid = 2;
966  }
967 
968  // column first matrix, as the axis in RSS
969  bv.axes.col(0) << E[0][max], E[1][max], E[2][max];
970  bv.axes.col(1) << E[0][mid], E[1][mid], E[2][mid];
971  bv.axes.col(2) << E[1][max] * E[2][mid] - E[1][mid] * E[2][max],
972  E[0][mid] * E[2][max] - E[0][max] * E[2][mid],
973  E[0][max] * E[1][mid] - E[0][mid] * E[1][max];
974 
975  // set rss origin, rectangle size and radius
976  getRadiusAndOriginAndRectangleSize(v, NULL, NULL, NULL, 16, bv.axes, bv.Tr,
977  bv.length, bv.radius);
978 
979  return bv;
980 }
981 
982 CoalScalar RSS::distance(const RSS& other, Vec3s* P, Vec3s* Q) const {
983  // compute what transform [R,T] that takes us from cs1 to cs2.
984  // [R,T] = [R1,T1]'[R2,T2] = [R1',-R1'T][R2,T2] = [R1'R2, R1'(T2-T1)]
985  // First compute the rotation part, then translation part
986  Matrix3s R(axes.transpose() * other.axes);
987  Vec3s T(axes.transpose() * (other.Tr - Tr));
988 
989  CoalScalar dist = rectDistance(R, T, length, other.length, P, Q);
990  dist -= (radius + other.radius);
991  return (dist < (CoalScalar)0.0) ? (CoalScalar)0.0 : dist;
992 }
993 
994 CoalScalar distance(const Matrix3s& R0, const Vec3s& T0, const RSS& b1,
995  const RSS& b2, Vec3s* P, Vec3s* Q) {
996  Matrix3s R(b1.axes.transpose() * R0 * b2.axes);
997  Vec3s Ttemp(R0 * b2.Tr + T0 - b1.Tr);
998 
999  Vec3s T(b1.axes.transpose() * Ttemp);
1000 
1001  CoalScalar dist = rectDistance(R, T, b1.length, b2.length, P, Q);
1002  dist -= (b1.radius + b2.radius);
1003  return (dist < (CoalScalar)0.0) ? (CoalScalar)0.0 : dist;
1004 }
1005 
1006 RSS translate(const RSS& bv, const Vec3s& t) {
1007  RSS res(bv);
1008  res.Tr += t;
1009  return res;
1010 }
1011 
1012 } // namespace coal
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
coal::segCoords
void segCoords(CoalScalar &t, CoalScalar &u, CoalScalar a, CoalScalar b, CoalScalar A_dot_B, CoalScalar A_dot_T, CoalScalar B_dot_T)
Finds the parameters t & u corresponding to the two closest points on a pair of line segments....
Definition: RSS.cpp:66
sep
const char * sep
Definition: obb.cpp:92
coal::RSS::distance
CoalScalar distance(const RSS &other, Vec3s *P=NULL, Vec3s *Q=NULL) const
the distance between two RSS; P and Q, if not NULL, return the nearest points
Definition: RSS.cpp:982
y
y
val
val
coal::CollisionRequest::security_margin
CoalScalar security_margin
Distance below which objects are considered in collision. See Collision.
Definition: coal/collision_data.h:328
collision_data.h
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
coal::RSS::radius
CoalScalar radius
Radius of sphere summed with rectangle to form RSS.
Definition: coal/BV/RSS.h:70
coal::inVoronoi
bool inVoronoi(CoalScalar a, CoalScalar b, CoalScalar Anorm_dot_B, CoalScalar Anorm_dot_T, CoalScalar A_dot_B, CoalScalar A_dot_T, CoalScalar B_dot_T)
Returns whether the nearest point on rectangle edge Pb + B*u, 0 <= u <= b, to the rectangle edge,...
Definition: RSS.cpp:94
coal::RSS::length
CoalScalar length[2]
Side lengths of rectangle.
Definition: coal/BV/RSS.h:67
R
R
coal::distance
COAL_DLLAPI CoalScalar distance(const Matrix3s &R0, const Vec3s &T0, const kIOS &b1, const kIOS &b2, Vec3s *P=NULL, Vec3s *Q=NULL)
Approximate distance between two kIOS bounding volumes.
Definition: kIOS.cpp:180
coal::RSS::contain
bool contain(const Vec3s &p) const
Check whether the RSS contains a point.
Definition: RSS.cpp:762
coal::eigen
void eigen(const Eigen::MatrixBase< Derived > &m, typename Derived::Scalar dout[3], Vector *vout)
compute the eigen vector and eigen vector of a matrix. dout is the eigen values, vout is the eigen ve...
Definition: coal/internal/tools.h:103
RSS.h
a
list a
coal::RSS::operator+
RSS operator+(const RSS &other) const
Return the merged RSS of current RSS and the other one.
Definition: RSS.cpp:907
coal::clipToRange
void clipToRange(CoalScalar &val, CoalScalar a, CoalScalar b)
Clip value between a and b.
Definition: RSS.cpp:48
coal::RSS::overlap
bool overlap(const RSS &other) const
Check collision between two RSS.
Definition: RSS.cpp:714
res
res
P
P
coal::RSS::operator+=
RSS & operator+=(const Vec3s &p)
A simple way to merge the RSS and a point, not compact.
Definition: RSS.cpp:793
coal::CollisionRequest
request to the collision algorithm
Definition: coal/collision_data.h:311
x
x
M
M
coal::translate
static AABB translate(const AABB &aabb, const Vec3s &t)
translate the center of AABB by t
Definition: coal/BV/AABB.h:233
coal::getRadiusAndOriginAndRectangleSize
COAL_DLLAPI void getRadiusAndOriginAndRectangleSize(Vec3s *ps, Vec3s *ps2, Triangle *ts, unsigned int *indices, unsigned int n, const Matrix3s &axes, Vec3s &origin, CoalScalar l[2], CoalScalar &r)
Compute the RSS bounding volume parameters: radius, rectangle size and the origin,...
Definition: BVH_utility.cpp:263
tools.h
coal::overlap
COAL_DLLAPI bool overlap(const Matrix3s &R0, const Vec3s &T0, const AABB &b1, const AABB &b2)
Check collision between two aabbs, b1 is in configuration (R0, T0) and b2 is in identity.
Definition: AABB.cpp:134
generate_distance_plot.b
float b
Definition: generate_distance_plot.py:7
coal::RSS::axes
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Matrix3s axes
Orientation of RSS. axis[i] is the ith column of the orientation matrix for the RSS; it is also the i...
Definition: coal/BV/RSS.h:61
coal::Matrix3s
Eigen::Matrix< CoalScalar, 3, 3 > Matrix3s
Definition: coal/data_types.h:81
coal::getCovariance
COAL_DLLAPI void getCovariance(Vec3s *ps, Vec3s *ps2, Triangle *ts, unsigned int *indices, unsigned int n, Matrix3s &M)
Compute the covariance matrix for a set or subset of points. if ts = null, then indices refer to poin...
Definition: BVH_utility.cpp:182
coal::RSS::Tr
Vec3s Tr
Origin of the rectangle in RSS.
Definition: coal/BV/RSS.h:64
BVH_utility.h
coal::rectDistance
CoalScalar rectDistance(const Matrix3s &Rab, Vec3s const &Tab, const CoalScalar a[2], const CoalScalar b[2], Vec3s *P=NULL, Vec3s *Q=NULL)
Distance between two oriented rectangles; P and Q (optional return values) are the closest points in ...
Definition: RSS.cpp:120
t
dictionary t
coal::RSS
A class for rectangle sphere-swept bounding volume.
Definition: coal/BV/RSS.h:53
coal::CoalScalar
double CoalScalar
Definition: coal/data_types.h:76
obb.v
list v
Definition: obb.py:48


hpp-fcl
Author(s):
autogenerated on Sat Nov 23 2024 03:44:59