24/09/2014
Как средствами AutoCAD определить расположение точки относительно контура.
Вопрос:
Есть ли встроенные средства для определения как расположена точка относительно контура в AutoCAD .NET API?
Ответ:
Специальных средств для этого нет. Но есть по меньшей мере два способа, которыми можно воспользоваться для этого:
- С использованием BREP .NET API (Autodesk.AutoCAD.BoundaryRepresentation) – Если превратить контур в Region, то можно будет воспользоваться возможностью Brep для определения положения точки внутри Region. Для этого можно воспользоваться методом BrepEntity.GetPointContainment, который возвращает объект-перечисление PointContainment, которое может принимать одно из трёх значений: Inside (внутри), Outside (снаружи), OnBoundary (на самом контуре).
- C использованием класса примитива MPolygon. Обычно этот класс используется в Civil 3D, но так как он есть и в базовом AutoCAD, то мы можем им воспользоваться.
В данной статье мы рассмотрим второй способ. Будем считать, что в качестве контура у нас имеется замкнутая полилиния. В общем случае она может иметь и дуговые сегменты, но не должна быть самопересекающейся – иначе теряется смысл понятия «внутри контура». Ниже пример команды, которая просит пользователя указать точку и полилинию. Обратите внимание на следующие моменты:
- В конструкторе класса происходит загрузка файла AcMPolygonObjXX.dbx, который необходим для нормальной работы сборки AcMPolygonMGD.dll (XX зависит от версии AutoCAD)
- Необходимо добавит ссылку на AcMPolygonMGD.dll для возможности работы с классом MPolygon
- Код не адаптирован для работы в ПСК отличной в МСК. Для адаптации указанную точку следует преобразовать из ПСК в МСК.
Код - C#: [Выделить]
- using System;
- using System.Reflection;
- using Autodesk.AutoCAD.Runtime;
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.Geometry;
- using Autodesk.AutoCAD.EditorInput;
- using AcEd = Autodesk.AutoCAD.EditorInput;
- using AcRx = Autodesk.AutoCAD.Runtime;
- using AcAp = Autodesk.AutoCAD.ApplicationServices;
- using AcDb = Autodesk.AutoCAD.DatabaseServices;
- using AcGe = Autodesk.AutoCAD.Geometry;
- //////////////////////////////////////////////////////////////////////////
- // Необходимо подключить ссылку на AcMPolygonMGD.dll !!!
- //////////////////////////////////////////////////////////////////////////
- [assembly: CommandClass(typeof(MakeContour.MyCommands))]
- namespace MakeContour
- {
- public class MyCommands
- {
- static MyCommands()
- {
- AcRx.SystemObjects.DynamicLinker
- .LoadModule("AcMPolygonObj" + AcAp.Application.Version.Major + ".dbx", false, false);
- }
- [CommandMethod("TestPointInContour")]
- public void TestPointInContour()
- {
- AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
- AcDb.Database db = doc.Database;
- AcEd.Editor ed = doc.Editor;
- AcEd.PromptPointOptions pr =
- new AcEd.PromptPointOptions("\nУкажите точку: ");
- AcEd.PromptPointResult res = ed.GetPoint(pr);
- if (res.Status != AcEd.PromptStatus.OK) return;
- AcEd.PromptEntityOptions pre =
- new AcEd.PromptEntityOptions("\nУкажите контур (замкнутую полилинию): ");
- pre.SetRejectMessage("Это не контур (полилиния)");
- pre.AddAllowedClass(typeof(AcDb.Polyline), true);
- AcEd.PromptEntityResult rese = ed.GetEntity(pre);
- if (rese.Status != AcEd.PromptStatus.OK) return;
- using (AcDb.MPolygon mp = new AcDb.MPolygon()) {
- using (AcDb.Polyline poly = rese.ObjectId.Open(AcDb.OpenMode.ForRead) as AcDb.Polyline) {
- try {
- mp.AppendLoopFromBoundary(poly, true, AcGe.Tolerance.Global.EqualPoint);
- if (mp.IsPointOnLoopBoundary(res.Value, 0, AcGe.Tolerance.Global.EqualPoint)) {
- ed.WriteMessage("\nТочка на границе контура!");
- } else if (mp.IsPointInsideMPolygon(res.Value, AcGe.Tolerance.Global.EqualPoint).Count > 0) {
- ed.WriteMessage("\nТочка внутри контура!");
- } else {
- ed.WriteMessage("\nТочка вне контура!");
- }
- } catch { }
- }
- }
- }
- }
- }
Автор: Александр Ривилис
Автор перевода: Александр Ривилис
Автор перевода: Александр Ривилис
Обсуждение: http://adn-cis.org/forum/index.php?topic=979
Опубликовано 24.09.2014