Dưới đây là một số mã giả được đề xuất. Phiên bản đơn giản đầu tiên, phiên bản mạnh mẽ hơn sau này (chỉ để giúp tách nguyên tắc khỏi các vết thương). phiên bản đơn giản:
// Assume the plane is given as the equation dot(N,X) + d = 0, where N is a (not
// neccessarily normalized) plane normal, and d is a scalar. Any way the plane is given -
// DistFromPlane should just let the input vector into the plane equation.
vector3d planeN;
float planeD;
float DistFromPlane(vector3d P)
{
// if N is not normalized this is *not* really the distance,
// but the computations work just the same.
return dot(planeN,P) + planeD;
}
bool GetSegmentPlaneIntersection(vector3d P1, vector3d P2, vector3d& outP)
{
float d1 = DistFromPlane(P1),
d2 = DistFromPlane(P2);
if (d1*d2 > 0) // points on the same side of plane
return false;
float t = d1/(d1 - d2); // 'time' of intersection point on the segment
outP = P1 + t * (P2 - P1);
return true;
}
void TrianglePlaneIntersection(vector3d triA, vector3d triB, vector3d triC,
vector3dArray& outSegTips)
{
vector3d IntersectionPoint;
if(GetSegmentPlaneIntersection(triA, triB, IntersectionPoint))
outSegTips.Add(IntersectionPoint);
if(GetSegmentPlaneIntersection(triB, triC, IntersectionPoint))
outSegTips.Add(IntersectionPoint);
if(GetSegmentPlaneIntersection(triC, triA, IntersectionPoint))
outSegTips.Add(IntersectionPoint);
}
Bây giờ thêm một số mạnh mẽ:
[Chỉnh sửa: Thêm xem xét rõ ràng đối với trường hợp của một đỉnh duy nhất trên máy bay]
vector3d planeN;
float planeD;
float DistFromPlane(vector3d P)
{
return dot(planeN,P) + planeD;
}
void GetSegmentPlaneIntersection(vector3d P1, vector3d P2, vector3dArray& outSegTips)
{
float d1 = DistFromPlane(P1),
d2 = DistFromPlane(P2);
bool bP1OnPlane = (abs(d1) < eps),
bP2OnPlane = (abs(d2) < eps);
if (bP1OnPlane)
outSegTips.Add(P1);
if (bP2OnPlane)
outSegTips.Add(P2);
if (bP1OnPlane && bP2OnPlane)
return;
if (d1*d2 > eps) // points on the same side of plane
return;
float t = d1/(d1 - d2); // 'time' of intersection point on the segment
outSegTips.Add(P1 + t * (P2 - P1));
}
void TrianglePlaneIntersection(vector3d triA, vector3d triB, vector3d triC,
vector3dArray& outSegTips)
{
GetSegmentPlaneIntersection(triA, triB, outSegTips));
GetSegmentPlaneIntersection(triB, triC, outSegTips));
GetSegmentPlaneIntersection(triC, triA, outSegTips));
RemoveDuplicates(outSegTips); // not listed here - obvious functionality
}
Hy vọng rằng đưa ra một ý tưởng, nhưng có vẫn còn một vài tối ưu tiềm năng. Ví dụ, nếu bạn tính toán các giao điểm này cho mỗi tam giác trong một lưới lớn, bạn có thể tính toán và nhớ cache DistanceFromPlane một lần trên mỗi đỉnh, và chỉ lấy nó cho mọi cạnh đỉnh tham gia. tùy thuộc vào kịch bản và biểu diễn dữ liệu của bạn.
thankyou rất nhiều, điều này giải thích nó tuyệt vời – Martin
Tôi nghĩ rằng nên được p1 + t * (p2 - p1); thay vì những gì bạn có? – Martin
cảm ơn! một lỗi đánh máy khác cũng được sửa. –