找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1718|回复: 0

[分享] Polyline LineSeg Angle

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-7-10 20:24:13 来自手机 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 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
    }
}
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-22 06:45 , Processed in 0.162842 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表