using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
namespace Function
{
public class Class1
{
[CommandMethod("ttest1")]
public void test()
{
List<ObjectId> ids = GetObjectsIds(new List<string> { "CIRCLE,LINE"});
if (ids.Count != 3) return;
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
//создаем 3 переменные
Line line = null;
Circle c1 = null;
Circle c2 = null;
//заполняем переменные
foreach (ObjectId id in ids)
{
Object obj = tr.GetObject(id, OpenMode.ForRead, false, true) as Object;
if (obj is Line && line == null)
{
line = obj as Line;
continue;
}
if (obj is Circle)
{
if (c1 == null)
{
c1 = obj as Circle;
continue;
};
if (c2 == null) c2 = obj as Circle;
}
}
//если выбрано 2 круга и линия продолжаем
if (line != null && c1 != null && c2 != null && c1.Radius > 0 && c2.Radius > 0)
{
//проверяем элементы на пересечения
using (Point3dCollection collection = new Point3dCollection())
{
c1.IntersectWith(c2, Intersect.OnBothOperands, collection, IntPtr.Zero, IntPtr.Zero);
if (collection.Count > 0)
{
tr.Abort();
return;
}
collection.Clear();
c1.IntersectWith(line, Intersect.OnBothOperands, collection, IntPtr.Zero, IntPtr.Zero);
if (collection.Count > 0)
{
tr.Abort();
return;
}
collection.Clear();
c2.IntersectWith(line, Intersect.OnBothOperands, collection, IntPtr.Zero, IntPtr.Zero);
if (collection.Count > 0)
{
tr.Abort();
return;
}
}
//проверяем что круги с одной стороны от линии
if ((line.GetClosestPointTo(c1.Center, true) - c1.Center).GetNormal() ==
(line.GetClosestPointTo(c2.Center, true) - c2.Center).GetNormal())
{
//получаем 3 точки примерного положеня касательных
Point3d p1 = line.GetClosestPointTo(c1.Center, true) + (line.GetClosestPointTo(c2.Center, true) - line.GetClosestPointTo(c1.Center, true)) * 0.5;
Point3d p2 = c1.Center + (p1 - c1.Center).GetNormal() * c1.Radius;
Point3d p3 = c2.Center + (p1 - c2.Center).GetNormal() * c2.Radius;
//просим мудрую машину построить нам круг)))
ed.Command("._Circle", "_3p", "_tan", p1, "_tan", p2, "_tan", p3);
}
}
tr.Commit();
}
}
private List<ObjectId> GetObjectsIds(List<string> objectTypes)
{
//создаем результат выбора
PromptSelectionResult pResult;
//создаем список Id
List<ObjectId> result = new List<ObjectId>();
if (objectTypes != null && objectTypes.Count > 0)
{
//создаем строку с типами объектов для фильтра
string objectTypesAll = string.Empty;
foreach (string objectType in objectTypes) objectTypesAll = objectTypesAll + objectType + ",";
objectTypesAll = objectTypesAll.Substring(0, objectTypesAll.Length - 1);
pResult = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.GetSelection(
new SelectionFilter(new TypedValue[] { new TypedValue((int)DxfCode.Start, objectTypesAll) }));
}
else
{
pResult = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.GetSelection();
}
//записываем Id выбранных объектов в список и возвращаем его
if (pResult.Status == PromptStatus.OK) result.AddRange(pResult.Value.GetObjectIds());
return result;
}
}
}