- UID
- 658062
- 积分
- 2147
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2008-10-22
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
本帖最后由 csharp 于 2014-7-10 20:45 编辑
http://forums.autodesk.com/autodesk/attachments/autodesk/152/33740/1/Code.txt
[CommandMethod("Test")]
public void Test()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
peo.SetRejectMessage("Only a polyline.");
peo.AddAllowedClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK) return;
try
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Autodesk.AutoCAD.DatabaseServices.Polyline pline = (Autodesk.AutoCAD.DatabaseServices.Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
if (pline.Closed)
{
for (int i = 0; i < pline.NumberOfVertices; i++)
{
LineSegment3d l1;
LineSegment3d l2;
if (i == pline.NumberOfVertices - 1)
{
l1 = pline.GetLineSegmentAt(i);
l2 = pline.GetLineSegmentAt(0);
}
else
{
l1 = pline.GetLineSegmentAt(i);
l2 = pline.GetLineSegmentAt(i + 1);
}
Vector3d v1 = l1.StartPoint - l1.EndPoint;
Vector3d v2 = l2.EndPoint - l2.StartPoint;
double angle = v1.GetAngleTo(v2);
bool res = IsInsideCurve(pline, l1.StartPoint + (l2.EndPoint - l1.StartPoint) * 0.5);
if (res)
{
ed.WriteMessage("\nAngle between {0} and {1}: {2}", i, 0, Converter.AngleToString(angle, AngularUnitFormat.Degrees, 2));
}
else
{
ed.WriteMessage("\nAngle between {0} and {1}: {2}", i, 0, Converter.AngleToString((2 * Math.PI) - angle, AngularUnitFormat.Degrees, 2));
}
}
}
}
}
catch
{
ed.WriteMessage("\nInvalid polyline.");
}
}
enum IncidenceType
{
kIncidenceToLeft = 0,
kIncidenceToRight,
kIncidenceToFront,
kIncidenceUnknown
};
IncidenceType CurveIncidence(Curve curve, double param, Vector3d dir, Vector3d normal)
{
Vector3d deriv1 = curve.GetFirstDerivative(param);
if (deriv1.IsParallelTo(dir))
{
// need second degree analysis
Vector3d deriv2 = curve.GetSecondDerivative(param);
if (deriv2.IsZeroLength() || deriv2.IsParallelTo(dir))
{
return IncidenceType.kIncidenceToFront;
}
else
{
if (deriv2.CrossProduct(dir).DotProduct(normal) < 0)
{
return IncidenceType.kIncidenceToRight;
}
else
{
return IncidenceType.kIncidenceToLeft;
}
}
}
if (deriv1.CrossProduct(dir).DotProduct(normal) < 0)
{
return IncidenceType.kIncidenceToLeft;
}
else
{
return IncidenceType.kIncidenceToRight;
}
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);
}
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
}
}
|
|