- UID
- 658062
- 积分
- 2147
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2008-10-22
- 最后登录
- 1970-1-1
|
楼主 |
发表于 2014-7-10 20:43:08
|
显示全部楼层
bool IsInsideCurve(Curve curve, Point3d testPt)
{
if (!curve.Closed)
{
// cannot be inside
return false;
}
Point3d ptOnCurve = curve.GetClosestPointTo(testPt, false);
if (testPt == ptOnCurve)
{
return true;
}
if (!curve.IsPlanar)
{
return false;
}
// check its planar
Plane plane = curve.GetPlane();
// make the test ray from the plane
double epsilon = 2e-6; // ( trust me on this )
Point3dCollection IntersectionPoints = new Point3dCollection();
Vector3d normal = plane.Normal;
Vector3d testVector = normal.GetPerpendicularVector();
using (Ray ray = new Ray())
{
ray.BasePoint = testPt;
int nGlancingHits = 0, numberOfInters = 0;
bool bRetryWithOtherRayDirection;
do
{
bRetryWithOtherRayDirection = false;
IntersectionPoints.Clear();
ray.UnitDir = testVector;
// fire the ray at the curve
curve.IntersectWith(ray,
Intersect.OnBothOperands,
IntersectionPoints,
IntPtr.Zero,
IntPtr.Zero);
numberOfInters = IntersectionPoints.Count;
if (numberOfInters == 0)
{
return false;
}
nGlancingHits = 0;
for (int i = 0; i < IntersectionPoints.Count; ++i)
{
double hitParam;
try
{
//This try/catch block circumvents an issue with GetParameterAtPoint API
hitParam = curve.GetParameterAtPoint(IntersectionPoints[i]);
}
catch
{
bRetryWithOtherRayDirection = true;
testVector = testVector.RotateBy(5.0 * Math.PI / 180.0, normal);
break;
}
double inParam = hitParam - epsilon;
double outParam = hitParam + epsilon;
//Loop back inside the curve if param is falling outside of range
if (inParam < curve.StartParam)
inParam = curve.EndParam - epsilon + (curve.StartParam - inParam);
if (outParam > curve.EndParam)
outParam = curve.StartParam + epsilon + (curve.EndParam - outParam);
IncidenceType inIncidence = CurveIncidence(curve, inParam, testVector, normal);
IncidenceType outIncidence = CurveIncidence(curve, outParam, testVector, normal);
if (inIncidence == IncidenceType.kIncidenceToFront || outIncidence == IncidenceType.kIncidenceToFront)
{
bRetryWithOtherRayDirection = true;
testVector = testVector.RotateBy(5.0 * Math.PI / 180.0, normal);
break;
}
if ((inIncidence == IncidenceType.kIncidenceToRight && outIncidence == IncidenceType.kIncidenceToLeft) ||
(inIncidence == IncidenceType.kIncidenceToLeft && outIncidence == IncidenceType.kIncidenceToRight))
{
nGlancingHits++;
}
}
}
while (bRetryWithOtherRayDirection);
return ((numberOfInters + nGlancingHits) % 2 == 1
}
}
|
|