using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using AcRx = Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices;
using AcDb = Autodesk.AutoCAD.DatabaseServices;
using AcGe = Autodesk.AutoCAD.Geometry;
using AcEd = Autodesk.AutoCAD.EditorInput;
[assembly: CommandClass(typeof(TestArc.MyCommands))]
namespace TestArc
{
public class MyCommands
{
/// <summary>
/// Функция на основе CircularArc3d создаёт Arc
/// </summary>
/// <param name="circArc"></param>
/// <returns></returns>
AcDb.Arc circArc3Arc(CircularArc3d circArc)
{
AcGe.Point3d center = circArc.Center;
AcGe.Vector3d normal = circArc.Normal;
AcGe.Vector3d refVec = circArc.ReferenceVector;
AcGe.Plane plane = new Plane(center, normal);
double ang = refVec.AngleOnPlane(plane);
return new AcDb.Arc(
center,
normal,
circArc.Radius,
circArc.StartAngle + ang,
circArc.EndAngle + ang
);
}
/// <summary>
/// Построение дуги по конечным точкам и точке центра
/// </summary>
[CommandMethod("TestArc1")]
public void TestArc1()
{
AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
AcEd.Editor ed = doc.Editor;
AcEd.PromptPointOptions pr1 =
new AcEd.PromptPointOptions("\nУкажите точку начала дуги: ");
AcEd.PromptPointOptions pr2 =
new AcEd.PromptPointOptions("\nУкажите точку конца дуги: ");
AcEd.PromptPointOptions prc =
new AcEd.PromptPointOptions("\nУкажите точку центра дуги: ");
AcEd.PromptPointResult res1, res2, resc;
if ((res1 = ed.GetPoint(pr1)).Status != AcEd.PromptStatus.OK ||
(res2 = ed.GetPoint(pr2)).Status != AcEd.PromptStatus.OK ||
(resc = ed.GetPoint(prc)).Status != AcEd.PromptStatus.OK)
return;
AcGe.Point3d p1 = res1.Value, p2 = res2.Value, pc = resc.Value;
double radius = (p1.DistanceTo(pc) + p2.DistanceTo(pc)) * 0.5;
AcGe.Point3d pMid = p1 + (p2 - p1) * 0.5;
pMid = pc + (pc - pMid).GetNormal() * radius;
AcGe.CircularArc3d arc3 = new AcGe.CircularArc3d(p1, pMid, p2);
using (AcDb.Arc arc = circArc3Arc(arc3))
{
using (AcDb.BlockTableRecord btr = doc.Database.CurrentSpaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
{
btr.AppendEntity(arc);
}
}
}
/// <summary>
/// Построение дуги по конечным точкам и промежуточной точке на дуге
/// </summary>
[CommandMethod("TestArc2")]
public void TestArc2()
{
AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
AcEd.Editor ed = doc.Editor;
AcEd.PromptPointOptions pr1 =
new AcEd.PromptPointOptions("\nУкажите точку начала дуги: ");
AcEd.PromptPointOptions pr2 =
new AcEd.PromptPointOptions("\nУкажите точку конца дуги: ");
AcEd.PromptPointOptions prm =
new AcEd.PromptPointOptions("\nУкажите промежуточную на дуге: ");
AcEd.PromptPointResult res1, res2, resm;
if ((res1 = ed.GetPoint(pr1)).Status != AcEd.PromptStatus.OK ||
(res2 = ed.GetPoint(pr2)).Status != AcEd.PromptStatus.OK ||
(resm = ed.GetPoint(prm)).Status != AcEd.PromptStatus.OK)
return;
AcGe.Point3d p1 = res1.Value, p2 = res2.Value, pMid = resm.Value;
if (p1.DistanceTo(pMid) + p2.DistanceTo(pMid) <= p1.DistanceTo(p2))
{
ed.WriteMessage("\nПо этим данным нельзя построить дугу!");
return;
}
AcGe.CircularArc3d arc3 = new AcGe.CircularArc3d(p1, pMid, p2);
using (AcDb.Arc arc = circArc3Arc(arc3))
{
using (AcDb.BlockTableRecord btr = doc.Database.CurrentSpaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
{
btr.AppendEntity(arc);
}
}
}
/// <summary>
/// Построение дуги по конечным точкам и радиусу
/// </summary>
[CommandMethod("TestArc3")]
public void TestArc3()
{
AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
AcEd.Editor ed = doc.Editor;
AcEd.PromptPointOptions pr1 =
new AcEd.PromptPointOptions("\nУкажите точку начала дуги: ");
AcEd.PromptPointOptions pr2 =
new AcEd.PromptPointOptions("\nУкажите точку конца дуги: ");
AcEd.PromptDistanceOptions prc =
new AcEd.PromptDistanceOptions("\nУкажите радиус дуги: ");
AcEd.PromptPointResult res1, res2;
AcEd.PromptDoubleResult resc;
if ((res1 = ed.GetPoint(pr1)).Status != AcEd.PromptStatus.OK ||
(res2 = ed.GetPoint(pr2)).Status != AcEd.PromptStatus.OK ||
(resc = ed.GetDistance(prc)).Status != AcEd.PromptStatus.OK)
return;
AcGe.Point3d p1 = res1.Value, p2 = res2.Value;
double radius = resc.Value;
if (radius <= p1.DistanceTo(p2) * 0.5)
{
ed.WriteMessage("\nПо этим данным нельзя построить дугу!");
return;
}
AcGe.Vector3d norm = AcGe.Vector3d.ZAxis;
AcGe.CircularArc3d a1 = new AcGe.CircularArc3d(p1, norm, radius);
AcGe.CircularArc3d a2 = new AcGe.CircularArc3d(p2, norm, radius);
AcGe.CurveCurveIntersector3d cint = new AcGe.CurveCurveIntersector3d(a1, a2, norm);
// Одно пересечение быть не может, так это значит
// что все точки лежат на одной прямой.
if (cint.NumberOfIntersectionPoints == 2) {
AcGe.Point3d pc1 = cint.GetIntersectionPoint(0);
AcGe.Point3d pc2 = cint.GetIntersectionPoint(1);
AcGe.CircularArc3d arc31 = new AcGe.CircularArc3d(p1, pc1, p2);
AcGe.CircularArc3d arc32 = new AcGe.CircularArc3d(p1, pc2, p2);
using (AcDb.Arc arc1 = circArc3Arc(arc31)) using (AcDb.Arc arc2 = circArc3Arc(arc32))
{
using (AcDb.BlockTableRecord btr = doc.Database.CurrentSpaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
{
if (arc1.StartPoint.DistanceTo(p1) < arc2.StartPoint.DistanceTo(p1))
btr.AppendEntity(arc1);
else
btr.AppendEntity(arc2);
}
}
}
}
}
}