Add methods to get intersections of mesh edges, project point on edge
This commit is contained in:
@@ -225,6 +225,100 @@ bool MeshGeomEdge::IntersectBoundingBox (const Base::BoundBox3f &rclBB) const
|
||||
return intrsectbox.Test();
|
||||
}
|
||||
|
||||
bool MeshGeomEdge::IntersectWithLine (const Base::Vector3f &rclPt,
|
||||
const Base::Vector3f &rclDir,
|
||||
Base::Vector3f &rclRes) const
|
||||
{
|
||||
const float eps = 1e-06f;
|
||||
Base::Vector3f n = _aclPoints[1] - _aclPoints[0];
|
||||
|
||||
// check angle between edge and the line direction, FLOAT_MAX is
|
||||
// returned for degenerated edges
|
||||
float fAngle = rclDir.GetAngle(n);
|
||||
if (fAngle == 0) {
|
||||
// parallel lines
|
||||
float distance = _aclPoints[0].DistanceToLine(rclPt, rclDir);
|
||||
if (distance < eps) {
|
||||
// lines are equal
|
||||
rclRes = _aclPoints[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // no intersection possible
|
||||
}
|
||||
|
||||
// that's the normal of a helper plane and its base at _aclPoints
|
||||
Base::Vector3f normal = n.Cross(rclDir);
|
||||
|
||||
// if the distance of rclPt to the plane is higher than eps then the
|
||||
// two lines are warped and there is no intersection possible
|
||||
if (fabs(rclPt.DistanceToPlane(_aclPoints[0], normal)) > eps)
|
||||
return false;
|
||||
|
||||
// get a second helper plane and get the intersection with the line
|
||||
Base::Vector3f normal2 = normal.Cross(n);
|
||||
|
||||
float s = ((_aclPoints[0] - rclPt) * normal2) / (rclDir * normal2);
|
||||
rclRes = rclPt + s * rclDir;
|
||||
|
||||
float dist1 = Base::Distance(_aclPoints[0], _aclPoints[1]);
|
||||
float dist2 = Base::Distance(_aclPoints[0], rclRes);
|
||||
float dist3 = Base::Distance(_aclPoints[1], rclRes);
|
||||
|
||||
return dist2 + dist3 <= dist1 + eps;
|
||||
}
|
||||
|
||||
void MeshGeomEdge::ProjectPointToLine (const Base::Vector3f &rclPoint,
|
||||
Base::Vector3f &rclProj) const
|
||||
{
|
||||
Base::Vector3f pt1 = rclPoint - _aclPoints[0];
|
||||
Base::Vector3f dir = _aclPoints[1] - _aclPoints[0];
|
||||
Base::Vector3f vec;
|
||||
vec.ProjectToLine(pt1, dir);
|
||||
rclProj = rclPoint + vec;
|
||||
}
|
||||
|
||||
void MeshGeomEdge::ClosestPointsToLine(const Base::Vector3f &linePt, const Base::Vector3f &lineDir,
|
||||
Base::Vector3f& rclPnt1, Base::Vector3f& rclPnt2) const
|
||||
{
|
||||
const float eps = 1e-06f;
|
||||
Base::Vector3f edgeDir = _aclPoints[1] - _aclPoints[0];
|
||||
|
||||
// check angle between edge and the line direction, FLOAT_MAX is
|
||||
// returned for degenerated edges
|
||||
float fAngle = lineDir.GetAngle(edgeDir);
|
||||
if (fAngle == 0) {
|
||||
// parallel lines
|
||||
float distance = _aclPoints[0].DistanceToLine(linePt, lineDir);
|
||||
if (distance < eps) {
|
||||
// lines are equal
|
||||
rclPnt1 = _aclPoints[0];
|
||||
rclPnt2 = _aclPoints[0];
|
||||
}
|
||||
else {
|
||||
rclPnt1 = _aclPoints[0];
|
||||
MeshGeomEdge edge;
|
||||
edge._aclPoints[0] = linePt;
|
||||
edge._aclPoints[1] = linePt + lineDir;
|
||||
edge.ProjectPointToLine(rclPnt1, rclPnt2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// that's the normal of a helper plane
|
||||
Base::Vector3f normal = edgeDir.Cross(lineDir);
|
||||
|
||||
// get a second helper plane and get the intersection with the line
|
||||
Base::Vector3f normal2 = normal.Cross(edgeDir);
|
||||
float s = ((_aclPoints[0] - linePt) * normal2) / (lineDir * normal2);
|
||||
rclPnt2 = linePt + s * lineDir;
|
||||
|
||||
// get a third helper plane and get the intersection with the line
|
||||
Base::Vector3f normal3 = normal.Cross(lineDir);
|
||||
float t = ((linePt - _aclPoints[0]) * normal3) / (edgeDir * normal3);
|
||||
rclPnt1 = _aclPoints[0] + t * edgeDir;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
MeshGeomFacet::MeshGeomFacet (void)
|
||||
|
||||
@@ -164,6 +164,22 @@ public:
|
||||
Base::BoundBox3f GetBoundBox () const;
|
||||
/** Checks if the edge intersects with the given bounding box. */
|
||||
bool IntersectBoundingBox (const Base::BoundBox3f &rclBB) const;
|
||||
/** Calculates the intersection point of the line defined by the base \a rclPt and the direction \a rclDir
|
||||
* with the edge. The intersection must be inside the edge. If there is no intersection false is returned.
|
||||
*/
|
||||
bool IntersectWithLine (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes) const;
|
||||
/**
|
||||
* Calculates the projection of a point onto the line defined by the edge. The caller must check if
|
||||
* the projection point is inside the edge.
|
||||
*/
|
||||
void ProjectPointToLine (const Base::Vector3f &rclPoint, Base::Vector3f &rclProj) const;
|
||||
/**
|
||||
* Get the closest points \a rclPnt1 and \a rclPnt2 of the line defined by this edge and the line
|
||||
* defined by \a rclPt and \a rclDir.
|
||||
* If the two points are identical then both lines intersect each other.
|
||||
*/
|
||||
void ClosestPointsToLine(const Base::Vector3f &linePt, const Base::Vector3f &lineDir,
|
||||
Base::Vector3f& rclPnt1, Base::Vector3f& rclPnt2) const;
|
||||
|
||||
public:
|
||||
Base::Vector3f _aclPoints[2]; /**< Corner points */
|
||||
|
||||
Reference in New Issue
Block a user