本帖最后由 lzh741206 于 2010-12-18 13:39 编辑
- public enum PointOnRegionType
- {
- Inside,
- On,
- Outside,
- Error
- }
- public static PointOnRegionType PointOnRegion(this IEnumerable<Point2d> pts, Point2d pt)
- {
- //遍历点集并生成首尾连接的多边形
- LoopList<Point2d> ptlst = new LoopList<Point2d>(pts);
- if(ptlst.Count < 3)
- return PointOnRegionType.Error;
- var ls2ds = new List<LineSegment2d>();
- foreach (var node in ptlst.GetNodes())
- {
- ls2ds.Add(new LineSegment2d(node.Value, node.Next.Value));
- }
- var cc2d = new CompositeCurve2d(ls2ds.ToArray());
- //在多边形上?
- if (cc2d.IsOn(pt, new Tolerance(1e-4, 1e-4)))
- return PointOnRegionType.On;
- //在最小包围矩形外?
- var bb2d = cc2d.BoundBlock;
- if (!bb2d.Contains(pt))
- return PointOnRegionType.Outside;
- //
- bool flag = false;
- foreach (var node in ptlst.GetNodes())
- {
- var pt1 = node.Value;
- var pt2 = node.Next.Value;
- if (pt.Y < pt1.Y && pt.Y < pt2.Y)
- continue;
- if (pt1.X < pt.X && pt2.X < pt.X)
- continue;
- Vector2d vec = pt2 - pt1;
- double t = (pt.X - pt1.X) / vec.X;
- double y = t * vec.Y + pt1.Y;
- if (y < pt.Y && t >= 0 && t <= 1)
- flag = !flag;
- }
- return flag ? PointOnRegionType.Inside : PointOnRegionType.Outside;
- }
复制代码 LoopList类在这里找http://bbs.mjtd.com/thread-82110-1-1.html
测试代码:
- [CommandMethod("t4")]
- public static void Test4()
- {
- Document doc = Application.DocumentManager.MdiActiveDocument;
- Editor ed = doc.Editor;
-
- PromptEntityOptions optsEnt = new PromptEntityOptions("\nSelect a LWPolyLine:");
- optsEnt.SetRejectMessage("\nNot a LWPolyLine!");
- optsEnt.AddAllowedClass(typeof(LWPolyline), false);
- PromptEntityResult resEnt = ed.GetEntity(optsEnt);
- if (resEnt.Status == PromptStatus.OK)
- {
- Database db = doc.Database;
- using (Transaction tr = db.TransactionManager.StartTransaction())
- {
- LWPolyline pl = tr.GetObject(resEnt.ObjectId, OpenMode.ForRead) as LWPolyline;
- var ptlst =
- Enumerable
- .Range(0, pl.NumberOfVertices)
- .Select(i => pl.GetPoint2dAt(i));
- PromptPointOptions optPnt = new PromptPointOptions("\nInput a Point:");
- optPnt.AllowNone = true;
- PromptPointResult resPnt = ed.GetPoint(optPnt);
- while (resPnt.Status == PromptStatus.OK)
- {
- var res = ptlst.PointOnRegion(resPnt.Value.Convert2d(new Plane()));
- ed.WriteMessage("\nPoint:{0},Result:{1}" ,resPnt.Value, res);
- resPnt = ed.GetPoint(optPnt);
- }
- }
- }
- }
|