• 数学篇 cad.net 判断点在多段线内-射线法


    矩形只是多段线的一种解,

    但是矩形可以利用叉乘做到快速求解.

    这方面可以自行去搞搞.

    这里提供一个最通用的.

    测试命令:

        public class JJ_test_ckk
        {
            [CommandMethod("JJ_test_ckk")]
            public void TT()
            {
                Editor ed = Acap.DocumentManager.MdiActiveDocument.Editor;
                Database db = Acap.DocumentManager.MdiActiveDocument.Database;
                ed.WriteMessage(Environment.NewLine + "惊惊net测试区:");
    
                var ppo = new PromptPointOptions(Environment.NewLine + "测试点:")
                {
                    AllowArbitraryInput = true,//任意输入
                    AllowNone = true//允许回车
                };
                var ppr = ed.GetPoint(ppo);//用户点选
                if (ppr.Status != PromptStatus.OK)
                {
                    return;
                }
    
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    var peo = new PromptEntityOptions(Environment.NewLine + "点选多段线")
                    {
                        AllowObjectOnLockedLayer = false,
                        AllowNone = false
                    };
    
                    var ent2 = ed.WhileEntsel(tr, peo, null, new EntityType[] { EntityType.Polyline });
                    if (ent2 is ObjectId idv && idv.IsOk())
                    {
                        Entity ent = idv.ToEntity(tr);
                        if (ent is Polyline pl && MathTool.IsPointInPL(ppr.Value, pl.GetPoint3ds())) 
                        {
                            ed.WriteMessage(Environment.NewLine + "内内内内内内内内");
                        }
                        else
                        {
                            ed.WriteMessage(Environment.NewLine + "外外外外外外外外外外外");
                        }
                    }
                    else
                    {
                        return;
                    }
                    tr.Commit();
                }
            }
        }
    View Code

    点选多段线函数:

       /// <summary>
            /// 点选直到满足条件
            /// </summary>
            /// <param name="ed">图形数据库</param> 
            /// <param name="entType">过滤类型,数组</param> 
            /// <param name="peo">块外</param>
            /// <param name="opt">块内</param>
            /// <returns>点选到的图元的ObjectId</returns>
            public static object WhileEntsel(this Editor ed, Transaction tr,
            PromptEntityOptions peo = null, PromptNestedEntityOptions opt = null, IEnumerable<EntityType> entType = null)
            {
                ed.SetImpliedSelection(new ObjectId[0]);  //清空当前选择集
                object idOrKeyword = null;
                ObjectId idget = ObjectId.Null;
                bool flag = true;
                PromptEntityResult res;
                PromptNestedEntityResult pnes;
                while (flag)
                {
                    if (peo != null)
                    {
                        res = ed.GetEntity(peo);
                        switch (res.Status)
                        {
                            case PromptStatus.Keyword:
                                idOrKeyword = res.StringResult;
                                flag = false;
                                break;
                            case PromptStatus.Cancel:
                            case PromptStatus.None:
                            case PromptStatus.Error:
                                flag = false;
                                break;
                            case PromptStatus.OK:
                                idget = res.ObjectId;
                                break;
                        }
                    }
                    else if (opt != null)
                    {
                        pnes = ed.GetNestedEntity(opt);
                        switch (pnes.Status)
                        {
                            case PromptStatus.Cancel:
                                flag = false;
                                break;
                            case PromptStatus.None:
                                flag = false;
                                break;
                            case PromptStatus.Error:
                                flag = false;
                                break;
                            case PromptStatus.OK:
                                idget = pnes.ObjectId;
                                break;
                        }
                    }
                    var listtype = new List<string>();
                    //类型要求为空,代表任何类型都接受,否则加入表内判断.
                    if (entType != null)
                    {
                        foreach (var item in entType)
                        {
                            listtype.Add(item.ToString());
                        }
                    }
                    if (idget.IsOk())
                    {
                        //图元类型匹配
                        Entity ent = idget.ToEntity(tr);
                        if (entType == null || entType.Count == 0)
                        {
                            flag = false;
                            idOrKeyword = idget;
                        }
                        else if (listtype.Contains(ent.GetType().Name))
                        {
                            flag = false;
                            idOrKeyword = idget;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                CadSystem.Setvar("errno", "0");//空格结束产生的错误系统变量,会影响到下一次使用错误系统变量的判断.
                return idOrKeyword;
            }
    View Code

    id.isok

            /// <summary>
            /// id有效,未被删除
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public static bool IsOk(this ObjectId id)
            {
                return !id.IsNull && id.IsValid && !id.IsErased && !id.IsEffectivelyErased && id.IsResident;
            }
    View Code

    射线法:  

            /// <summary>
            /// 判断点在闭合多段线内(线上也是内)射线法
            /// </summary>
            /// <param name="p">判断的点</param>
            /// <param name="pts">边界点集</param>
            /// <returns></returns> 
            public static bool IsPointInPL(Point3d p, IEnumerable<Point3d> pts)
            {
                var px = p.X;
                var py = p.Y;
                var flag = false;
    
                var poly = pts.ToArray();
                int l = poly.Length;
                int j = l - 1;
    
                for (var i = 0; i < l; i++)
                {
                    var pt1x = poly[i].X;//
                    var pt1y = poly[i].Y;
                    var pt2x = poly[j].X;//
                    var pt2y = poly[j].Y;
    
                    // 点与多边形顶点重合
                    if ((pt1x.Eq(px) && pt1y.Eq(py)) || (pt2x.Eq(px) && pt2y.Eq(py)))
                    {
                        return true;
                    }
                    // 判断线段两端点是否在射线两侧
                    if ((pt1y < py && pt2y >= py) || (pt1y >= py && pt2y < py))
                    {
                        // 线段上与射线 Y 坐标相同的点的 X 坐标
                        var x = pt1x + (py - pt1y) * (pt2x - pt1x) / (pt2y - pt1y);
    
                        // 点在多边形的边上
                        if (x.Eq(px))
                        {
                            return true;
                        }
                        // 射线穿过多边形的边界
                        if (x > px)
                        {
                            flag = !flag;
                        }
                    }
                    j = i;
                }
                // 射线穿过多边形边界的次数为奇数时点在多边形内
                return flag;
            }
    View Code

    (完)

  • 相关阅读:
    Eclipse中添加MyEclipse插件
    用GWT开发的HelloGWT程序
    GWT module 'xxx' may need to be (re)compiled解决办法
    GWTDesigner_v5.1.0破解码
    Firefox火狐广告过滤插件Adblock Plus过滤规则包[中文维护小组]
    工程师们,不要想一辈子靠技术混饭吃
    PHP生成类似类似优酷、腾讯视频等其他视频链的ID
    (外挂破解)Cheat Engine(内存修改工具)V6.2中文版软件介绍
    ucos-ii核心算法分析(转)
    Websocket,ProtoBuffer,Hightlight,JSON 等,最近遇到的一些知识点小结
  • 原文地址:https://www.cnblogs.com/JJBox/p/14062009.html
Copyright © 2020-2023  润新知