Hi!
I'm trying to draw an arc in Autocad, with class Arc, and the constructor
Arc(Point3d center, Vector3d normal, double radius, double startAngle, double endAngle).
My problem is that I don't find almost anything in the documentation, and when I draw an arc, it has a phase difference between the place in what it should be and the place it is. I think it depends on the quadrant, but I'm not sure.
The angles that I use are measured in the reference system XY. Maybe the reference system changes depending on the plane of the arc (?)
My class is really simple:
public class Arco2d { # region ATRIBUTOS Point2d startPoint; Point2d middlePoint; Point2d endPoint; Point2d centro; Point3d centro3d; double radio; double startAngle; double endAngle; #endregion #region GETTERS public Point2d StartPoint { get { return startPoint; } } public Point2d MiddlePoint { get { return middlePoint; } } public Point2d EndPoint { get { return endPoint; } } public Point2d Centro { get { return centro; } } public Point3d Centro3d { get { return centro3d; } } public double Radio { get { return radio; } } public double StartAngle { get { return startAngle; } } public double EndAngle { get { return endAngle; } } #endregion /// <summary> /// Construye un arco a partir de tres puntos. /// </summary> /// <param name="startPoint"></param> /// <param name="middlePoint"></param> /// <param name="endPoint"></param> public Arco2d(Point2d startPoint, Point2d middlePoint, Point2d endPoint) { this.startPoint = startPoint; this.middlePoint = middlePoint; this.endPoint = endPoint; calcRadioYCentro(startPoint, middlePoint, endPoint); calcAngulos(); } # region Métodos Privados /// <summary> /// Calcula el radio y centro del círculo que contiene al arco definido por los tres puntos. /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="p3"></param> private void calcRadioYCentro(Point2d p1, Point2d p2, Point2d p3) { double k1 = p1.X * p2.Y + p3.X * p1.Y + p2.X * p3.Y - p1.X * p3.Y - p2.X * p1.Y - p3.X * p2.Y; double k2 = -(p1.X * p1.X + p1.Y * p1.Y); double k3 = p2.Y - p3.Y; double k4 = p3.X - p2.X; double k5 = p2.X * p2.X + p2.Y * p2.Y; double k6 = p1.Y - p3.Y; double k7 = p3.X - p1.X; double k8 = -(p3.X * p3.X + p3.Y * p3.Y); double k9 = p1.Y - p2.Y; double k10 = p2.X - p1.X; double a1 = p2.X * p3.Y - p3.X * p2.Y; double a2 = p1.X * p3.Y - p3.X * p1.Y; double a3 = p1.X * p2.Y - p2.X * p1.Y; double a = (k2 * k3 + k5 * k6 + k8 * k9) / k1; double b = (k2 * k4 + k5 * k7 + k8 * k10) / k1; double c = -(k2 * a1 + k5 * a2 + k8 * a3) / k1; double centrox = a / 2; double centroy = b / 2; this.radio = Math.Sqrt(c + (a / 2) * (a / 2) + (b / 2) * (b / 2)); this.centro = new Point2d(-centrox, -centroy); } /// <summary> /// Calcula los ángulos de comienzo y fin del arco. /// </summary> private void calcAngulos() { double d1, d2, d3, d4; d1 = startPoint.Y - centro.Y; d2 = endPoint.Y - centro.Y; d3 = startPoint.X - centro.X; d4 = endPoint.X - centro.X; startAngle = Math.Atan(d1 / d3); endAngle = Math.Atan(d2 / d4); if (d3 < 0) // cuadrante 2 y 3 { startAngle += Math.PI; } else if (d3 > 0 && d1 < 0) // cuadrante 4 { startAngle += 2 * Math.PI; } if (d4 < 0) // cuadrante 2 y 3 { endAngle += Math.PI; } else if (d4 > 0 && d2 < 0) // cuadrante 4 { endAngle += 2 * Math.PI; } } #endregion #region Métodos Públicos /// <summary> /// Dibuja un objeto Arc a partir de los parámetros de esta clase. /// </summary> public void addArc2layer() { // Get the current document and database Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // Start a transaction using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Open the Block table for read BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // Open the Block table record Model space for write BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; Arc acArc = new Arc(new Point3d(centro.X, centro.Y, 0), radio, startAngle, endAngle); acArc.SetDatabaseDefaults(); // Add the new object to the block table record and the transaction acBlkTblRec.AppendEntity(acArc); acTrans.AddNewlyCreatedDBObject(acArc, true); // Save the new line to the database acTrans.Commit(); } } /// <summary> /// Aún sin terminar. Revisar. /// </summary> /// <param name="centro"></param> /// <param name="normal"></param> public void addArc2layer(Point3d centro, Vector3d normal) { // Get the current document and database Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; // Start a transaction using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { // Open the Block table for read BlockTable acBlkTbl; acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; // Open the Block table record Model space for write BlockTableRecord acBlkTblRec; acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; Arc acArc = new Arc(centro, normal, radio, startAngle, endAngle); acArc.SetDatabaseDefaults(); // Add the new object to the block table record and the transaction acBlkTblRec.AppendEntity(acArc); acTrans.AddNewlyCreatedDBObject(acArc, true); // Save the new line to the database acTrans.Commit(); } } #endregion }
Any help would be great!
Solved! Go to Solution.
Solved by hgasty1001. Go to Solution.
Here is a link to a blog post that starts a series of jigging a semi-circle.
There is a ton of information on this blog if you go back through old posts. Please be aware though the links at the bottom to go forwards and backwards through the blog are reversed. Next post takes you back and previous post takes you forward.
It is not the exact information that you want but it should help you.
At the end, it was not really the answer to my question but it contains a function to solve it:
CircularArc3d cArc = new CircularArc3d(pStart, pMid, pEnd);
double angle = cArc.ReferenceVector.AngleOnPlane(new Plane(cArc.Center,cArc.Normal));
Arc arc = new Arc(cArc.Center, cArc.Normal, cArc.Radius, cArc.StartAngle + angle, cArc.EndAngle + angle);
I think this function calculates the phase difference caused by the plane (?) so now I can draw an 3d Arc in all the planes. I think it means that I was right about the behaviour of the Arc parameters. 😄
Thank you too much!
Can't find what you're looking for? Ask the community or share your knowledge.