double GLWidget::DistanceToFiniteLine(AVector v, AVector w, AVector p) { float zero_epsilon = std::numeric_limits<float>::epsilon(); // Return minimum distance between line segment vw and point p double l2 = v.DistanceSquared(w); // i.e. |w-v|^2 - avoid a sqrt if (l2 > -zero_epsilon && l2 < zero_epsilon) return p.Distance(v); // v == w case // Consider the line extending the segment, parameterized as v + t (w - v). // We find projection of point p onto the line. // It falls where t = [(p-v) . (w-v)] / |w-v|^2 double t = (p - v).Dot(w - v) / l2; if (t < 0.0) { return p.Distance(v); } // Beyond the 'v' end of the segment else if (t > 1.0) { return p.Distance(w); } // Beyond the 'w' end of the segment AVector projection = v + (w - v) * t; // Projection falls on the segment return p.Distance(projection); }
// not compatible with dirichlet boundary condition AVector QuadMesh::GetClosestPointFromBorders(AVector pt) { AVector closestPt = pt; float dist = std::numeric_limits<float>::max(); std::vector<ALine> borderLines; borderLines.push_back(ALine(_leftStartPt, _rightStartPt)); borderLines.push_back(ALine(_leftEndPt, _rightEndPt)); borderLines.push_back(ALine(_leftStartPt, _leftEndPt)); borderLines.push_back(ALine(_rightStartPt, _rightEndPt)); for(uint a = 0; a < borderLines.size(); a++) { AVector cPt = UtilityFunctions::GetClosestPoint(borderLines[a].GetPointA(), borderLines[a].GetPointB(), pt); if(pt.Distance(cPt) < dist) { dist = pt.Distance(cPt); closestPt = cPt; } } return closestPt; }