Directory: | ./ |
---|---|
File: | src/intersect.cpp |
Date: | 2025-04-01 09:23:31 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 177 | 206 | 85.9% |
Branches: | 334 | 616 | 54.2% |
Line | Branch | Exec | Source |
---|---|---|---|
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 | |||
36 | /** \author Jia Pan */ | ||
37 | |||
38 | #include "coal/internal/intersect.h" | ||
39 | #include "coal/internal/tools.h" | ||
40 | |||
41 | #include <iostream> | ||
42 | #include <limits> | ||
43 | #include <vector> | ||
44 | #include <cmath> | ||
45 | |||
46 | namespace coal { | ||
47 | |||
48 | ✗ | bool Intersect::buildTrianglePlane(const Vec3s& v1, const Vec3s& v2, | |
49 | const Vec3s& v3, Vec3s* n, Scalar* t) { | ||
50 | ✗ | Vec3s n_ = (v2 - v1).cross(v3 - v1); | |
51 | ✗ | Scalar norm2 = n_.squaredNorm(); | |
52 | ✗ | if (norm2 > 0) { | |
53 | ✗ | *n = n_ / sqrt(norm2); | |
54 | ✗ | *t = n->dot(v1); | |
55 | ✗ | return true; | |
56 | } | ||
57 | ✗ | return false; | |
58 | } | ||
59 | |||
60 | 863428 | void TriangleDistance::segPoints(const Vec3s& P, const Vec3s& A, const Vec3s& Q, | |
61 | const Vec3s& B, Vec3s& VEC, Vec3s& X, | ||
62 | Vec3s& Y) { | ||
63 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | Vec3s T; |
64 | Scalar A_dot_A, B_dot_B, A_dot_B, A_dot_T, B_dot_T; | ||
65 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | Vec3s TMP; |
66 | |||
67 |
2/4✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 863428 times.
✗ Branch 5 not taken.
|
863428 | T = Q - P; |
68 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | A_dot_A = A.dot(A); |
69 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | B_dot_B = B.dot(B); |
70 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | A_dot_B = A.dot(B); |
71 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | A_dot_T = A.dot(T); |
72 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | B_dot_T = B.dot(T); |
73 | |||
74 | // t parameterizes ray P,A | ||
75 | // u parameterizes ray Q,B | ||
76 | |||
77 | Scalar t, u; | ||
78 | |||
79 | // compute t for the closest point on ray P,A to | ||
80 | // ray Q,B | ||
81 | |||
82 | 863428 | Scalar denom = A_dot_A * B_dot_B - A_dot_B * A_dot_B; | |
83 | |||
84 | 863428 | t = (A_dot_T * B_dot_B - B_dot_T * A_dot_B) / denom; | |
85 | |||
86 | // clamp result so t is on the segment P,A | ||
87 | |||
88 |
6/6✓ Branch 0 taken 514785 times.
✓ Branch 1 taken 348643 times.
✓ Branch 3 taken 5462 times.
✓ Branch 4 taken 509323 times.
✓ Branch 5 taken 354105 times.
✓ Branch 6 taken 509323 times.
|
863428 | if ((t < 0) || std::isnan(t)) |
89 | 354105 | t = 0; | |
90 |
2/2✓ Branch 0 taken 377618 times.
✓ Branch 1 taken 131705 times.
|
509323 | else if (t > 1) |
91 | 377618 | t = 1; | |
92 | |||
93 | // find u for point on ray Q,B closest to point at t | ||
94 | |||
95 | 863428 | u = (t * A_dot_B - B_dot_T) / B_dot_B; | |
96 | |||
97 | // if u is on segment Q,B, t and u correspond to | ||
98 | // closest points, otherwise, clamp u, recompute and | ||
99 | // clamp t | ||
100 | |||
101 |
5/6✓ Branch 0 taken 520802 times.
✓ Branch 1 taken 342626 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 520802 times.
✓ Branch 5 taken 342626 times.
✓ Branch 6 taken 520802 times.
|
863428 | if ((u <= 0) || std::isnan(u)) { |
102 |
1/2✓ Branch 1 taken 342626 times.
✗ Branch 2 not taken.
|
342626 | Y = Q; |
103 | |||
104 | 342626 | t = A_dot_T / A_dot_A; | |
105 | |||
106 |
5/6✓ Branch 0 taken 234676 times.
✓ Branch 1 taken 107950 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 234676 times.
✓ Branch 5 taken 107950 times.
✓ Branch 6 taken 234676 times.
|
342626 | if ((t <= 0) || std::isnan(t)) { |
107 |
1/2✓ Branch 1 taken 107950 times.
✗ Branch 2 not taken.
|
107950 | X = P; |
108 |
2/4✓ Branch 1 taken 107950 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 107950 times.
✗ Branch 5 not taken.
|
107950 | VEC = Q - P; |
109 |
2/2✓ Branch 0 taken 196196 times.
✓ Branch 1 taken 38480 times.
|
234676 | } else if (t >= 1) { |
110 |
2/4✓ Branch 1 taken 196196 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 196196 times.
✗ Branch 5 not taken.
|
196196 | X = P + A; |
111 |
2/4✓ Branch 1 taken 196196 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 196196 times.
✗ Branch 5 not taken.
|
196196 | VEC = Q - X; |
112 | } else { | ||
113 |
3/6✓ Branch 1 taken 38480 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 38480 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 38480 times.
✗ Branch 8 not taken.
|
38480 | X = P + A * t; |
114 |
1/2✓ Branch 1 taken 38480 times.
✗ Branch 2 not taken.
|
38480 | TMP = T.cross(A); |
115 |
1/2✓ Branch 1 taken 38480 times.
✗ Branch 2 not taken.
|
38480 | VEC = A.cross(TMP); |
116 | } | ||
117 |
2/2✓ Branch 0 taken 461339 times.
✓ Branch 1 taken 59463 times.
|
520802 | } else if (u >= 1) { |
118 |
2/4✓ Branch 1 taken 461339 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 461339 times.
✗ Branch 5 not taken.
|
461339 | Y = Q + B; |
119 | |||
120 | 461339 | t = (A_dot_B + A_dot_T) / A_dot_A; | |
121 | |||
122 |
5/6✓ Branch 0 taken 249655 times.
✓ Branch 1 taken 211684 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 249655 times.
✓ Branch 5 taken 211684 times.
✓ Branch 6 taken 249655 times.
|
461339 | if ((t <= 0) || std::isnan(t)) { |
123 |
1/2✓ Branch 1 taken 211684 times.
✗ Branch 2 not taken.
|
211684 | X = P; |
124 |
2/4✓ Branch 1 taken 211684 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 211684 times.
✗ Branch 5 not taken.
|
211684 | VEC = Y - P; |
125 |
2/2✓ Branch 0 taken 197404 times.
✓ Branch 1 taken 52251 times.
|
249655 | } else if (t >= 1) { |
126 |
2/4✓ Branch 1 taken 197404 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 197404 times.
✗ Branch 5 not taken.
|
197404 | X = P + A; |
127 |
2/4✓ Branch 1 taken 197404 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 197404 times.
✗ Branch 5 not taken.
|
197404 | VEC = Y - X; |
128 | } else { | ||
129 |
3/6✓ Branch 1 taken 52251 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 52251 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 52251 times.
✗ Branch 8 not taken.
|
52251 | X = P + A * t; |
130 |
2/4✓ Branch 1 taken 52251 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 52251 times.
✗ Branch 5 not taken.
|
52251 | T = Y - P; |
131 |
1/2✓ Branch 1 taken 52251 times.
✗ Branch 2 not taken.
|
52251 | TMP = T.cross(A); |
132 |
1/2✓ Branch 1 taken 52251 times.
✗ Branch 2 not taken.
|
52251 | VEC = A.cross(TMP); |
133 | } | ||
134 | } else { | ||
135 |
3/6✓ Branch 1 taken 59463 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 59463 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 59463 times.
✗ Branch 8 not taken.
|
59463 | Y = Q + B * u; |
136 | |||
137 |
5/6✓ Branch 0 taken 45255 times.
✓ Branch 1 taken 14208 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 45255 times.
✓ Branch 5 taken 14208 times.
✓ Branch 6 taken 45255 times.
|
59463 | if ((t <= 0) || std::isnan(t)) { |
138 |
1/2✓ Branch 1 taken 14208 times.
✗ Branch 2 not taken.
|
14208 | X = P; |
139 |
1/2✓ Branch 1 taken 14208 times.
✗ Branch 2 not taken.
|
14208 | TMP = T.cross(B); |
140 |
1/2✓ Branch 1 taken 14208 times.
✗ Branch 2 not taken.
|
14208 | VEC = B.cross(TMP); |
141 |
2/2✓ Branch 0 taken 28834 times.
✓ Branch 1 taken 16421 times.
|
45255 | } else if (t >= 1) { |
142 |
2/4✓ Branch 1 taken 28834 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28834 times.
✗ Branch 5 not taken.
|
28834 | X = P + A; |
143 |
2/4✓ Branch 1 taken 28834 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28834 times.
✗ Branch 5 not taken.
|
28834 | T = Q - X; |
144 |
1/2✓ Branch 1 taken 28834 times.
✗ Branch 2 not taken.
|
28834 | TMP = T.cross(B); |
145 |
1/2✓ Branch 1 taken 28834 times.
✗ Branch 2 not taken.
|
28834 | VEC = B.cross(TMP); |
146 | } else { | ||
147 |
3/6✓ Branch 1 taken 16421 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16421 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 16421 times.
✗ Branch 8 not taken.
|
16421 | X = P + A * t; |
148 |
1/2✓ Branch 1 taken 16421 times.
✗ Branch 2 not taken.
|
16421 | VEC = A.cross(B); |
149 |
3/4✓ Branch 1 taken 16421 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8141 times.
✓ Branch 4 taken 8280 times.
|
16421 | if (VEC.dot(T) < 0) { |
150 |
2/4✓ Branch 1 taken 8141 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8141 times.
✗ Branch 5 not taken.
|
8141 | VEC = VEC * (-1); |
151 | } | ||
152 | } | ||
153 | } | ||
154 | 863428 | } | |
155 | |||
156 | 340088 | Scalar TriangleDistance::sqrTriDistance(const Vec3s S[3], const Vec3s T[3], | |
157 | Vec3s& P, Vec3s& Q) { | ||
158 | // Compute vectors along the 6 sides | ||
159 | |||
160 |
3/4✓ Branch 1 taken 1020264 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1020264 times.
✓ Branch 4 taken 340088 times.
|
1360352 | Vec3s Sv[3]; |
161 |
3/4✓ Branch 1 taken 1020264 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1020264 times.
✓ Branch 4 taken 340088 times.
|
1360352 | Vec3s Tv[3]; |
162 |
1/2✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
|
340088 | Vec3s VEC; |
163 | |||
164 |
2/4✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340088 times.
✗ Branch 5 not taken.
|
340088 | Sv[0] = S[1] - S[0]; |
165 |
2/4✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340088 times.
✗ Branch 5 not taken.
|
340088 | Sv[1] = S[2] - S[1]; |
166 |
2/4✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340088 times.
✗ Branch 5 not taken.
|
340088 | Sv[2] = S[0] - S[2]; |
167 | |||
168 |
2/4✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340088 times.
✗ Branch 5 not taken.
|
340088 | Tv[0] = T[1] - T[0]; |
169 |
2/4✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340088 times.
✗ Branch 5 not taken.
|
340088 | Tv[1] = T[2] - T[1]; |
170 |
2/4✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340088 times.
✗ Branch 5 not taken.
|
340088 | Tv[2] = T[0] - T[2]; |
171 | |||
172 | // For each edge pair, the vector connecting the closest points | ||
173 | // of the edges defines a slab (parallel planes at head and tail | ||
174 | // enclose the slab). If we can show that the off-edge vertex of | ||
175 | // each triangle is outside of the slab, then the closest points | ||
176 | // of the edges are the closest points for the triangles. | ||
177 | // Even if these tests fail, it may be helpful to know the closest | ||
178 | // points found, and whether the triangles were shown disjoint | ||
179 | |||
180 |
4/8✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340088 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 340088 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 340088 times.
✗ Branch 11 not taken.
|
340088 | Vec3s V, Z, minP, minQ; |
181 | Scalar mindd; | ||
182 | 340088 | int shown_disjoint = 0; | |
183 | |||
184 |
2/4✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340088 times.
✗ Branch 5 not taken.
|
340088 | mindd = (S[0] - T[0]).squaredNorm() + 1; // Set first minimum safely high |
185 | |||
186 |
2/2✓ Branch 0 taken 473004 times.
✓ Branch 1 taken 3415 times.
|
476419 | for (int i = 0; i < 3; ++i) { |
187 |
2/2✓ Branch 0 taken 863428 times.
✓ Branch 1 taken 136331 times.
|
999759 | for (int j = 0; j < 3; ++j) { |
188 | // Find closest points on edges i & j, plus the | ||
189 | // vector (and distance squared) between these points | ||
190 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | segPoints(S[i], Sv[i], T[j], Tv[j], VEC, P, Q); |
191 | |||
192 |
2/4✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 863428 times.
✗ Branch 5 not taken.
|
863428 | V = Q - P; |
193 |
1/2✓ Branch 1 taken 863428 times.
✗ Branch 2 not taken.
|
863428 | Scalar dd = V.dot(V); |
194 | |||
195 | // Verify this closest point pair only if the distance | ||
196 | // squared is less than the minimum found thus far. | ||
197 | |||
198 |
2/2✓ Branch 0 taken 716285 times.
✓ Branch 1 taken 147143 times.
|
863428 | if (dd <= mindd) { |
199 |
1/2✓ Branch 1 taken 716285 times.
✗ Branch 2 not taken.
|
716285 | minP = P; |
200 |
1/2✓ Branch 1 taken 716285 times.
✗ Branch 2 not taken.
|
716285 | minQ = Q; |
201 | 716285 | mindd = dd; | |
202 | |||
203 |
2/4✓ Branch 1 taken 716285 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 716285 times.
✗ Branch 5 not taken.
|
716285 | Z = S[(i + 2) % 3] - P; |
204 |
1/2✓ Branch 1 taken 716285 times.
✗ Branch 2 not taken.
|
716285 | Scalar a = Z.dot(VEC); |
205 |
2/4✓ Branch 1 taken 716285 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 716285 times.
✗ Branch 5 not taken.
|
716285 | Z = T[(j + 2) % 3] - Q; |
206 |
1/2✓ Branch 1 taken 716285 times.
✗ Branch 2 not taken.
|
716285 | Scalar b = Z.dot(VEC); |
207 | |||
208 |
4/4✓ Branch 0 taken 436584 times.
✓ Branch 1 taken 279701 times.
✓ Branch 2 taken 336673 times.
✓ Branch 3 taken 99911 times.
|
716285 | if ((a <= 0) && (b >= 0)) return dd; |
209 | |||
210 |
1/2✓ Branch 1 taken 379612 times.
✗ Branch 2 not taken.
|
379612 | Scalar p = V.dot(VEC); |
211 | |||
212 |
2/2✓ Branch 0 taken 99775 times.
✓ Branch 1 taken 279837 times.
|
379612 | if (a < 0) a = 0; |
213 |
2/2✓ Branch 0 taken 239538 times.
✓ Branch 1 taken 140074 times.
|
379612 | if (b > 0) b = 0; |
214 |
2/2✓ Branch 0 taken 349955 times.
✓ Branch 1 taken 29657 times.
|
379612 | if ((p - a + b) > 0) shown_disjoint = 1; |
215 | } | ||
216 | } | ||
217 | } | ||
218 | |||
219 | // No edge pairs contained the closest points. | ||
220 | // either: | ||
221 | // 1. one of the closest points is a vertex, and the | ||
222 | // other point is interior to a face. | ||
223 | // 2. the triangles are overlapping. | ||
224 | // 3. an edge of one triangle is parallel to the other's face. If | ||
225 | // cases 1 and 2 are not true, then the closest points from the 9 | ||
226 | // edge pairs checks above can be taken as closest points for the | ||
227 | // triangles. | ||
228 | // 4. possibly, the triangles were degenerate. When the | ||
229 | // triangle points are nearly colinear or coincident, one | ||
230 | // of above tests might fail even though the edges tested | ||
231 | // contain the closest points. | ||
232 | |||
233 | // First check for case 1 | ||
234 | |||
235 |
1/2✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
|
3415 | Vec3s Sn; |
236 | Scalar Snl; | ||
237 | |||
238 |
1/2✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
|
3415 | Sn = Sv[0].cross(Sv[1]); // Compute normal to S triangle |
239 |
1/2✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
|
3415 | Snl = Sn.dot(Sn); // Compute square of length of normal |
240 | |||
241 | // If cross product is long enough, | ||
242 | |||
243 |
1/2✓ Branch 0 taken 3415 times.
✗ Branch 1 not taken.
|
3415 | if (Snl > 1e-15) { |
244 | // Get projection lengths of T points | ||
245 | |||
246 |
1/2✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
|
3415 | Vec3s Tp; |
247 | |||
248 |
2/4✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3415 times.
✗ Branch 5 not taken.
|
3415 | V = S[0] - T[0]; |
249 |
2/4✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3415 times.
✗ Branch 5 not taken.
|
3415 | Tp[0] = V.dot(Sn); |
250 | |||
251 |
2/4✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3415 times.
✗ Branch 5 not taken.
|
3415 | V = S[0] - T[1]; |
252 |
2/4✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3415 times.
✗ Branch 5 not taken.
|
3415 | Tp[1] = V.dot(Sn); |
253 | |||
254 |
2/4✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3415 times.
✗ Branch 5 not taken.
|
3415 | V = S[0] - T[2]; |
255 |
2/4✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3415 times.
✗ Branch 5 not taken.
|
3415 | Tp[2] = V.dot(Sn); |
256 | |||
257 | // If Sn is a separating direction, | ||
258 | // find point with smallest projection | ||
259 | |||
260 | 3415 | int point = -1; | |
261 |
11/14✓ Branch 1 taken 3415 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1275 times.
✓ Branch 4 taken 2140 times.
✓ Branch 6 taken 1275 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 678 times.
✓ Branch 9 taken 597 times.
✓ Branch 11 taken 678 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 451 times.
✓ Branch 14 taken 227 times.
✓ Branch 15 taken 451 times.
✓ Branch 16 taken 2964 times.
|
3415 | if ((Tp[0] > 0) && (Tp[1] > 0) && (Tp[2] > 0)) { |
262 |
4/6✓ Branch 1 taken 451 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 451 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 272 times.
✓ Branch 7 taken 179 times.
|
451 | if (Tp[0] < Tp[1]) |
263 | 272 | point = 0; | |
264 | else | ||
265 | 179 | point = 1; | |
266 |
4/6✓ Branch 1 taken 451 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 451 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 153 times.
✓ Branch 7 taken 298 times.
|
451 | if (Tp[2] < Tp[point]) point = 2; |
267 |
11/14✓ Branch 1 taken 2964 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2140 times.
✓ Branch 4 taken 824 times.
✓ Branch 6 taken 2140 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1616 times.
✓ Branch 9 taken 524 times.
✓ Branch 11 taken 1616 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1361 times.
✓ Branch 14 taken 255 times.
✓ Branch 15 taken 1361 times.
✓ Branch 16 taken 1603 times.
|
2964 | } else if ((Tp[0] < 0) && (Tp[1] < 0) && (Tp[2] < 0)) { |
268 |
4/6✓ Branch 1 taken 1361 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1361 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 813 times.
✓ Branch 7 taken 548 times.
|
1361 | if (Tp[0] > Tp[1]) |
269 | 813 | point = 0; | |
270 | else | ||
271 | 548 | point = 1; | |
272 |
4/6✓ Branch 1 taken 1361 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1361 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 515 times.
✓ Branch 7 taken 846 times.
|
1361 | if (Tp[2] > Tp[point]) point = 2; |
273 | } | ||
274 | |||
275 | // If Sn is a separating direction, | ||
276 | |||
277 |
2/2✓ Branch 0 taken 1812 times.
✓ Branch 1 taken 1603 times.
|
3415 | if (point >= 0) { |
278 | 1812 | shown_disjoint = 1; | |
279 | |||
280 | // Test whether the point found, when projected onto the | ||
281 | // other triangle, lies within the face. | ||
282 | |||
283 |
2/4✓ Branch 1 taken 1812 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1812 times.
✗ Branch 5 not taken.
|
1812 | V = T[point] - S[0]; |
284 |
1/2✓ Branch 1 taken 1812 times.
✗ Branch 2 not taken.
|
1812 | Z = Sn.cross(Sv[0]); |
285 |
3/4✓ Branch 1 taken 1812 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1727 times.
✓ Branch 4 taken 85 times.
|
1812 | if (V.dot(Z) > 0) { |
286 |
2/4✓ Branch 1 taken 1727 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1727 times.
✗ Branch 5 not taken.
|
1727 | V = T[point] - S[1]; |
287 |
1/2✓ Branch 1 taken 1727 times.
✗ Branch 2 not taken.
|
1727 | Z = Sn.cross(Sv[1]); |
288 |
3/4✓ Branch 1 taken 1727 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1627 times.
✓ Branch 4 taken 100 times.
|
1727 | if (V.dot(Z) > 0) { |
289 |
2/4✓ Branch 1 taken 1627 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1627 times.
✗ Branch 5 not taken.
|
1627 | V = T[point] - S[2]; |
290 |
1/2✓ Branch 1 taken 1627 times.
✗ Branch 2 not taken.
|
1627 | Z = Sn.cross(Sv[2]); |
291 |
3/4✓ Branch 1 taken 1627 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1589 times.
✓ Branch 4 taken 38 times.
|
1627 | if (V.dot(Z) > 0) { |
292 | // T[point] passed the test - it's a closest point for | ||
293 | // the T triangle; the other point is on the face of S | ||
294 |
4/8✓ Branch 1 taken 1589 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1589 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1589 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1589 times.
✗ Branch 11 not taken.
|
1589 | P = T[point] + Sn * (Tp[point] / Snl); |
295 |
1/2✓ Branch 1 taken 1589 times.
✗ Branch 2 not taken.
|
1589 | Q = T[point]; |
296 |
2/4✓ Branch 1 taken 1589 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1589 times.
✗ Branch 5 not taken.
|
1589 | return (P - Q).squaredNorm(); |
297 | } | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | |||
303 |
1/2✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
|
1826 | Vec3s Tn; |
304 | Scalar Tnl; | ||
305 | |||
306 |
1/2✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
|
1826 | Tn = Tv[0].cross(Tv[1]); |
307 |
1/2✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
|
1826 | Tnl = Tn.dot(Tn); |
308 | |||
309 |
1/2✓ Branch 0 taken 1826 times.
✗ Branch 1 not taken.
|
1826 | if (Tnl > 1e-15) { |
310 |
1/2✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
|
1826 | Vec3s Sp; |
311 | |||
312 |
2/4✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1826 times.
✗ Branch 5 not taken.
|
1826 | V = T[0] - S[0]; |
313 |
2/4✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1826 times.
✗ Branch 5 not taken.
|
1826 | Sp[0] = V.dot(Tn); |
314 | |||
315 |
2/4✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1826 times.
✗ Branch 5 not taken.
|
1826 | V = T[0] - S[1]; |
316 |
2/4✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1826 times.
✗ Branch 5 not taken.
|
1826 | Sp[1] = V.dot(Tn); |
317 | |||
318 |
2/4✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1826 times.
✗ Branch 5 not taken.
|
1826 | V = T[0] - S[2]; |
319 |
2/4✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1826 times.
✗ Branch 5 not taken.
|
1826 | Sp[2] = V.dot(Tn); |
320 | |||
321 | 1826 | int point = -1; | |
322 |
11/14✓ Branch 1 taken 1826 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 766 times.
✓ Branch 4 taken 1060 times.
✓ Branch 6 taken 766 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 162 times.
✓ Branch 9 taken 604 times.
✓ Branch 11 taken 162 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 46 times.
✓ Branch 14 taken 116 times.
✓ Branch 15 taken 46 times.
✓ Branch 16 taken 1780 times.
|
1826 | if ((Sp[0] > 0) && (Sp[1] > 0) && (Sp[2] > 0)) { |
323 |
4/6✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 46 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 32 times.
|
46 | if (Sp[0] < Sp[1]) |
324 | 14 | point = 0; | |
325 | else | ||
326 | 32 | point = 1; | |
327 |
4/6✓ Branch 1 taken 46 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 46 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 41 times.
|
46 | if (Sp[2] < Sp[point]) point = 2; |
328 |
11/14✓ Branch 1 taken 1780 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1060 times.
✓ Branch 4 taken 720 times.
✓ Branch 6 taken 1060 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 409 times.
✓ Branch 9 taken 651 times.
✓ Branch 11 taken 409 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 294 times.
✓ Branch 14 taken 115 times.
✓ Branch 15 taken 294 times.
✓ Branch 16 taken 1486 times.
|
1780 | } else if ((Sp[0] < 0) && (Sp[1] < 0) && (Sp[2] < 0)) { |
329 |
4/6✓ Branch 1 taken 294 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 294 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 137 times.
✓ Branch 7 taken 157 times.
|
294 | if (Sp[0] > Sp[1]) |
330 | 137 | point = 0; | |
331 | else | ||
332 | 157 | point = 1; | |
333 |
4/6✓ Branch 1 taken 294 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 294 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 104 times.
✓ Branch 7 taken 190 times.
|
294 | if (Sp[2] > Sp[point]) point = 2; |
334 | } | ||
335 | |||
336 |
2/2✓ Branch 0 taken 340 times.
✓ Branch 1 taken 1486 times.
|
1826 | if (point >= 0) { |
337 | 340 | shown_disjoint = 1; | |
338 | |||
339 |
2/4✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340 times.
✗ Branch 5 not taken.
|
340 | V = S[point] - T[0]; |
340 |
1/2✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
|
340 | Z = Tn.cross(Tv[0]); |
341 |
2/4✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 340 times.
✗ Branch 4 not taken.
|
340 | if (V.dot(Z) > 0) { |
342 |
2/4✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340 times.
✗ Branch 5 not taken.
|
340 | V = S[point] - T[1]; |
343 |
1/2✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
|
340 | Z = Tn.cross(Tv[1]); |
344 |
2/4✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 340 times.
✗ Branch 4 not taken.
|
340 | if (V.dot(Z) > 0) { |
345 |
2/4✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340 times.
✗ Branch 5 not taken.
|
340 | V = S[point] - T[2]; |
346 |
1/2✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
|
340 | Z = Tn.cross(Tv[2]); |
347 |
2/4✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 340 times.
✗ Branch 4 not taken.
|
340 | if (V.dot(Z) > 0) { |
348 |
1/2✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
|
340 | P = S[point]; |
349 |
4/8✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 340 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 340 times.
✗ Branch 11 not taken.
|
340 | Q = S[point] + Tn * (Sp[point] / Tnl); |
350 |
2/4✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 340 times.
✗ Branch 5 not taken.
|
340 | return (P - Q).squaredNorm(); |
351 | } | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | } | ||
356 | |||
357 | // Case 1 can't be shown. | ||
358 | // If one of these tests showed the triangles disjoint, | ||
359 | // we assume case 3 or 4, otherwise we conclude case 2, | ||
360 | // that the triangles overlap. | ||
361 | |||
362 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1486 times.
|
1486 | if (shown_disjoint) { |
363 | ✗ | P = minP; | |
364 | ✗ | Q = minQ; | |
365 | ✗ | return mindd; | |
366 | } else | ||
367 | 1486 | return 0; | |
368 | } | ||
369 | |||
370 | 340088 | Scalar TriangleDistance::sqrTriDistance(const Vec3s& S1, const Vec3s& S2, | |
371 | const Vec3s& S3, const Vec3s& T1, | ||
372 | const Vec3s& T2, const Vec3s& T3, | ||
373 | Vec3s& P, Vec3s& Q) { | ||
374 |
3/4✓ Branch 1 taken 1020264 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1020264 times.
✓ Branch 4 taken 340088 times.
|
1360352 | Vec3s S[3]; |
375 |
3/4✓ Branch 1 taken 1020264 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1020264 times.
✓ Branch 4 taken 340088 times.
|
1360352 | Vec3s T[3]; |
376 |
1/2✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
|
340088 | S[0] = S1; |
377 |
1/2✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
|
340088 | S[1] = S2; |
378 |
1/2✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
|
340088 | S[2] = S3; |
379 |
1/2✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
|
340088 | T[0] = T1; |
380 |
1/2✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
|
340088 | T[1] = T2; |
381 |
1/2✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
|
340088 | T[2] = T3; |
382 | |||
383 |
1/2✓ Branch 1 taken 340088 times.
✗ Branch 2 not taken.
|
680176 | return sqrTriDistance(S, T, P, Q); |
384 | } | ||
385 | |||
386 | ✗ | Scalar TriangleDistance::sqrTriDistance(const Vec3s S[3], const Vec3s T[3], | |
387 | const Matrix3s& R, const Vec3s& Tl, | ||
388 | Vec3s& P, Vec3s& Q) { | ||
389 | ✗ | Vec3s T_transformed[3]; | |
390 | ✗ | T_transformed[0] = R * T[0] + Tl; | |
391 | ✗ | T_transformed[1] = R * T[1] + Tl; | |
392 | ✗ | T_transformed[2] = R * T[2] + Tl; | |
393 | |||
394 | ✗ | return sqrTriDistance(S, T_transformed, P, Q); | |
395 | } | ||
396 | |||
397 | ✗ | Scalar TriangleDistance::sqrTriDistance(const Vec3s S[3], const Vec3s T[3], | |
398 | const Transform3s& tf, Vec3s& P, | ||
399 | Vec3s& Q) { | ||
400 | ✗ | Vec3s T_transformed[3]; | |
401 | ✗ | T_transformed[0] = tf.transform(T[0]); | |
402 | ✗ | T_transformed[1] = tf.transform(T[1]); | |
403 | ✗ | T_transformed[2] = tf.transform(T[2]); | |
404 | |||
405 | ✗ | return sqrTriDistance(S, T_transformed, P, Q); | |
406 | } | ||
407 | |||
408 | 336487 | Scalar TriangleDistance::sqrTriDistance(const Vec3s& S1, const Vec3s& S2, | |
409 | const Vec3s& S3, const Vec3s& T1, | ||
410 | const Vec3s& T2, const Vec3s& T3, | ||
411 | const Matrix3s& R, const Vec3s& Tl, | ||
412 | Vec3s& P, Vec3s& Q) { | ||
413 |
3/6✓ Branch 1 taken 336487 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 336487 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 336487 times.
✗ Branch 8 not taken.
|
336487 | Vec3s T1_transformed = R * T1 + Tl; |
414 |
3/6✓ Branch 1 taken 336487 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 336487 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 336487 times.
✗ Branch 8 not taken.
|
336487 | Vec3s T2_transformed = R * T2 + Tl; |
415 |
3/6✓ Branch 1 taken 336487 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 336487 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 336487 times.
✗ Branch 8 not taken.
|
336487 | Vec3s T3_transformed = R * T3 + Tl; |
416 |
1/2✓ Branch 1 taken 336487 times.
✗ Branch 2 not taken.
|
336487 | return sqrTriDistance(S1, S2, S3, T1_transformed, T2_transformed, |
417 | 672974 | T3_transformed, P, Q); | |
418 | } | ||
419 | |||
420 | ✗ | Scalar TriangleDistance::sqrTriDistance(const Vec3s& S1, const Vec3s& S2, | |
421 | const Vec3s& S3, const Vec3s& T1, | ||
422 | const Vec3s& T2, const Vec3s& T3, | ||
423 | const Transform3s& tf, Vec3s& P, | ||
424 | Vec3s& Q) { | ||
425 | ✗ | Vec3s T1_transformed = tf.transform(T1); | |
426 | ✗ | Vec3s T2_transformed = tf.transform(T2); | |
427 | ✗ | Vec3s T3_transformed = tf.transform(T3); | |
428 | ✗ | return sqrTriDistance(S1, S2, S3, T1_transformed, T2_transformed, | |
429 | ✗ | T3_transformed, P, Q); | |
430 | } | ||
431 | |||
432 | } // namespace coal | ||
433 |