.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Create Arc with constructor Arc(center, normal, radius, startAngle, endAngle)

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
Anonymous
882 Views, 3 Replies

Create Arc with constructor Arc(center, normal, radius, startAngle, endAngle)

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!

3 REPLIES 3
Message 2 of 4
Keith.Brown
in reply to: Anonymous

Here is a link to a blog post that starts a series of jigging a semi-circle.

 

http://spiderinnet1.typepad.com/blog/2014/10/autocad-net-entityjig-jig-semi-circle-with-start-and-en...

 

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.

Message 3 of 4
hgasty1001
in reply to: Anonymous

Hi,

 

See the solution posted by Alexander Rivilis here

He uses a CircularArc3D object to construct an Arc.

 

Gaston Nunez

 

Message 4 of 4
Anonymous
in reply to: hgasty1001

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.

Post to forums  

Forma Design Contest


Autodesk Design & Make Report