矩形只是多段线的一种解,
但是矩形可以利用叉乘做到快速求解.
这方面可以自行去搞搞.
这里提供一个最通用的.
测试命令:

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(); } } }
点选多段线函数:

/// <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; }
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; }
射线法:

/// <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; }
(完)