------------------------------------------------------------------------------
| 381 | |
| 382 | //------------------------------------------------------------------------------ |
| 383 | int vtkPolygon::EvaluatePosition(const double x[3], double closestPoint[3], int& subId, |
| 384 | double pcoords[3], double& minDist2, double weights[]) |
| 385 | { |
| 386 | int i; |
| 387 | double p0[3], p10[3], l10, p20[3], l20, n[3], cp[3]; |
| 388 | double ray[3], bounds[6]; |
| 389 | |
| 390 | subId = 0; |
| 391 | this->ParameterizePolygon(p0, p10, l10, p20, l20, n); |
| 392 | this->InterpolateFunctions(x, weights); |
| 393 | vtkPlane::ProjectPoint(x, p0, n, cp); |
| 394 | |
| 395 | for (i = 0; i < 3; i++) |
| 396 | { |
| 397 | ray[i] = cp[i] - p0[i]; |
| 398 | } |
| 399 | pcoords[0] = vtkMath::Dot(ray, p10) / (l10 * l10); |
| 400 | pcoords[1] = vtkMath::Dot(ray, p20) / (l20 * l20); |
| 401 | pcoords[2] = 0.0; |
| 402 | |
| 403 | // Make sure that the bounding box has non-zero volume, so that all |
| 404 | // bounding box sides have non-zero thickness. This prevents tolerancing |
| 405 | // issues when the polygon lies exactly on a coordinate plane. |
| 406 | vtkBoundingBox bbox(this->GetBounds()); |
| 407 | bbox.InflateSlice(VTK_POLYGON_TOL); |
| 408 | bbox.GetBounds(bounds); |
| 409 | |
| 410 | if (pcoords[0] >= 0.0 && pcoords[0] <= 1.0 && pcoords[1] >= 0.0 && pcoords[1] <= 1.0 && |
| 411 | (vtkPolygon::PointInPolygon(cp, this->Points->GetNumberOfPoints(), |
| 412 | static_cast<vtkDoubleArray*>(this->Points->GetData())->GetPointer(0), bounds, |
| 413 | n) == VTK_POLYGON_INSIDE)) |
| 414 | { |
| 415 | if (closestPoint) |
| 416 | { |
| 417 | closestPoint[0] = cp[0]; |
| 418 | closestPoint[1] = cp[1]; |
| 419 | closestPoint[2] = cp[2]; |
| 420 | minDist2 = vtkMath::Distance2BetweenPoints(x, closestPoint); |
| 421 | } |
| 422 | return 1; |
| 423 | } |
| 424 | |
| 425 | // If here, point is outside of polygon, so need to find distance to boundary |
| 426 | // |
| 427 | else |
| 428 | { |
| 429 | double t, dist2; |
| 430 | int numPts; |
| 431 | double closest[3]; |
| 432 | const double *pt1, *pt2; |
| 433 | |
| 434 | if (closestPoint) |
| 435 | { |
| 436 | numPts = this->Points->GetNumberOfPoints(); |
| 437 | // Efficient point access |
| 438 | const auto pointsArray = vtkDoubleArray::FastDownCast(this->Points->GetData()); |
| 439 | if (!pointsArray) |
| 440 | { |
no test coverage detected