| 196 | } |
| 197 | |
| 198 | std::tuple< double, geode::Point3D > pivot_point_triangle_distance( |
| 199 | const geode::Point3D& point, |
| 200 | const geode::Triangle3D& triangle, |
| 201 | geode::local_index_t v0 ) |
| 202 | { |
| 203 | const auto v1 = v0 == 2 ? 0 : v0 + 1; |
| 204 | const auto v2 = v1 == 2 ? 0 : v1 + 1; |
| 205 | const auto& vertices = triangle.vertices(); |
| 206 | const geode::Vector3D edge0{ vertices[v0], vertices[v1] }; |
| 207 | const geode::Vector3D edge1{ vertices[v0], vertices[v2] }; |
| 208 | const auto a00 = edge0.length2(); |
| 209 | const auto a01 = edge0.dot( edge1 ); |
| 210 | const auto a11 = edge1.length2(); |
| 211 | const geode::Vector3D diff{ vertices[v0], point }; |
| 212 | const auto b0 = -diff.dot( edge0 ); |
| 213 | const auto b1 = -diff.dot( edge1 ); |
| 214 | |
| 215 | auto f00 = b0; |
| 216 | auto f10 = b0 + a00; |
| 217 | auto f01 = b0 + a01; |
| 218 | |
| 219 | std::array< double, 2 > p0, p1, p; |
| 220 | double dt1, h0, h1; |
| 221 | |
| 222 | if( f00 >= 0 ) |
| 223 | { |
| 224 | if( f01 >= 0 ) |
| 225 | { // (1) p0 = (0,0), p1 = (0,1), H(z) = G(L(z)) |
| 226 | get_min_edge02( a11, b1, p ); |
| 227 | } |
| 228 | else |
| 229 | { // (2) p0 = (0,t10), p1 = (t01,1-t01), |
| 230 | // H(z) = (t11 - t10)*G(L(z)) |
| 231 | p0[0] = 0; |
| 232 | p0[1] = f00 / ( f00 - f01 ); |
| 233 | p1[0] = f01 / ( f01 - f10 ); |
| 234 | p1[1] = 1 - p1[0]; |
| 235 | dt1 = p1[1] - p0[1]; |
| 236 | h0 = dt1 * ( a11 * p0[1] + b1 ); |
| 237 | if( h0 >= 0 ) |
| 238 | { |
| 239 | get_min_edge02( a11, b1, p ); |
| 240 | } |
| 241 | else |
| 242 | { |
| 243 | h1 = dt1 * ( a01 * p1[0] + a11 * p1[1] + b1 ); |
| 244 | if( h1 <= 0 ) |
| 245 | { |
| 246 | get_min_edge12( a01, a11, b1, f10, f01, p ); |
| 247 | } |
| 248 | else |
| 249 | { |
| 250 | get_min_interior( p0, h0, p1, h1, p ); |
| 251 | } |
| 252 | } |
| 253 | } |
| 254 | } |
| 255 | else if( f01 <= 0 ) |
no test coverage detected