Given the startpoint, endpoint, and centerpoint,, draw an arc (incorrect)

Given the startpoint, endpoint, and centerpoint,, draw an arc (incorrect)

1127204185
Advocate Advocate
3,127 Views
17 Replies
Message 1 of 18

Given the startpoint, endpoint, and centerpoint,, draw an arc (incorrect)

1127204185
Advocate
Advocate

Three points of space

1、startpoint    AcGePoint3d& pt1

2、endpoint  AcGePoint3d& pt2

3、centerpoint  AcGePoint3d& ptcen

 1.png

 

	static AcDbArc* CreatArc(const AcGePoint3d& pt1, const AcGePoint3d& pt2, const AcGePoint3d& ptcen, bool mode)
	{
		AcGePoint3d ptmid = AcGePoint3d((pt1.x + pt2.x) * 0.5, (pt1.y + pt2.y) * 0.5, (pt1.z + pt2.z) * 0.5);
		AcGeVector3d vecmid = ptmid - ptcen;
		vecmid.normalize();
		ptmid = mode ? ptcen + vecmid * (ptcen.distanceTo(pt1)) : ptcen - vecmid * (ptcen.distanceTo(pt1));
		AcGeCircArc3d geArc(pt1, ptmid, pt2);
		AcDbArc* pArc = new AcDbArc(geArc.center(), geArc.normal(), geArc.radius(), geArc.startAng(), geArc.endAng());
		return  pArc;
	}

 

0 Likes
Accepted solutions (1)
3,128 Views
17 Replies
Replies (17)
Message 2 of 18

ynapeu
Advocate
Advocate
Accepted solution

please try this

void CreateArc3D(const AcGePoint3d& center, const AcGePoint3d& startPoint, const AcGePoint3d& endPoint)
{
AcGeVector3d vec1 = startPoint - center;
AcGeVector3d vec2 = endPoint - center;
AcGeVector3d normal = vec1.crossProduct(vec2);
normal.normalize(); // Normieren des Normalenvektors

AcGeVector3d xAxis = vec1.normal();
AcGeVector3d yAxis = normal.crossProduct(xAxis);

AcGePlane plane(center, normal);
AcGePoint2d start2D = plane.paramOf(startPoint);
AcGePoint2d end2D = plane.paramOf(endPoint);

double radius = center.distanceTo(startPoint);

double startAngle = AcGeVector2d(start2D).angle();
double endAngle = AcGeVector2d(end2D).angle();

AcDbArc* pArc = new AcDbArc(center, normal, radius, startAngle, endAngle);
.
.
}

0 Likes
Message 3 of 18

1127204185
Advocate
Advocate

Thank you. Is there an algorithm that can divide this arc equally?

0 Likes
Message 4 of 18

1127204185
Advocate
Advocate
Thank you.
0 Likes
Message 5 of 18

1127204185
Advocate
Advocate

const AcGePoint3d& center, const AcGePoint3d& startPoint, const AcGePoint3d& endPoint What if the three points are collinear?
AcGeVector3d normal = ?
AcGeVector2d(start2D)==start2D.asVector()?

 

I just want to solve for three non collinear points, generate an arc, and obtain the node coordinates of the arc segments?

0 Likes
Message 6 of 18

ynapeu
Advocate
Advocate

If the three points are collinear, they all lie on a straight line. This means that no unique circle can be formed through these three points. Typically, for constructing a circle, it is expected that the points do not lie on a straight line, as a circle requires at least two different directions to define both the center and the radius unambiguously. However, if they are collinear, no circle can exist mathematically.

0 Likes
Message 7 of 18

daniel_cadext
Advisor
Advisor

You can also have a look at using AcGeCircArc3d and acdbAssignGelibCurveToAcDbCurve. AcGeCircArc3d has a constructor that accepts three points

 

import traceback
from pyrx_imp import Ap, Db, Ed, Ge, Gi, Gs, Rx

def PyRxCmd_doit():
    try:
        db = Db.curDb()
        ps, pnt1 = Ed.Editor.getPoint("\nFirst")
        ps, pnt3 = Ed.Editor.getPoint("\nSecond")
        ps, rad = Ed.Editor.getDouble("\nRadius")
        pnt2 = pnt1 + ((pnt3 - pnt1) * 0.5)
        pnt2 = pnt2 + (Ge.Vector3d.kXAxis * rad)

        garc = Ge.CircArc3d(pnt1,pnt2,pnt3)
        crv = Db.Arc()
        Db.Core.assignGelibCurveToAcDbCurve(garc,crv)
        db.addToModelspace(crv)
        
    except Exception as err:
        traceback.print_exception(err)
Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 8 of 18

1127204185
Advocate
Advocate

1.png

 

 

	AcGePoint3d p1, p2, p3;  
	    if (RTNORM != acedGetPoint(NULL, L"\n第一点:: ", asDblArray(p1))  
		||  RTNORM != acedGetPoint(NULL, L"\n第二点:: ", asDblArray(p2))  
		||  RTNORM != acedGetPoint(NULL, L"\n第三点:: ", asDblArray(p3)))  
	{
		acutPrintf(L"\nFunction canceled\n" );     
		return;   
	}  
	AcGeCircArc3d geArc(p1, p2, p3);
	AcDbArc *pArc = NULL;
	AcDbCurve::createFromAcGeCurve(geArc, (AcDbCurve*&) pArc);

 

 

 

AcDbCurve::createFromAcGeCurve(geArc, (AcDbCurve*&) pArc);  Does this function not exist in lower versions?

 

double startAngle = AcGeVector2d(start2D).angle();
double endAngle = AcGeVector2d(end2D).angle();

How to ask correctly? startAngle   endAngle ?

 

 

0 Likes
Message 9 of 18

daniel_cadext
Advisor
Advisor

the global versions should be in since before 2013

acdbConvertAcDbCurveToGelibCurve
acdbConvertGelibCurveToAcDbCurve
acdbAssignGelibCurveToAcDbCurve

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 10 of 18

1127204185
Advocate
Advocate
vs2010?
0 Likes
Message 11 of 18

daniel_cadext
Advisor
Advisor

I don’t know, but you can probably do that your self from the properties of the constructed AcGeCircArc3d

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 12 of 18

1127204185
Advocate
Advocate
Then we need to recalculate startAngle and endAngle?
0 Likes
Message 13 of 18

daniel_cadext
Advisor
Advisor

no, those will be calculated for you in AcGeCircArc3d class

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 14 of 18

daniel_cadext
Advisor
Advisor

yeah, seems is doing some extra math

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 15 of 18

daniel_cadext
Advisor
Advisor

 

import traceback
from pyrx_imp import Ap, Db, Ed, Ge, Gi, Gs, Rx

def PyRxCmd_doit():
    try:
        db = Db.curDb()
        ps, pnt1 = Ed.Editor.getPoint("\nFirst")
        ps, pnt3 = Ed.Editor.getPoint("\nSecond")
        ps, rad = Ed.Editor.getDouble("\nRadius")
        pnt2 = pnt1 + ((pnt3 - pnt1) * 0.5)
        pnt2 = pnt2 + (Ge.Vector3d.kXAxis * rad)

        garc = Ge.CircArc3d(pnt1,pnt2,pnt3)
        crv =  Db.Core.convertGelibCurveToAcDbCurve(garc)
        garc2 =  Ge.CircArc3d.cast(crv.getAcGeCurve())
        
        print(garc.center(),garc.radius(),garc.startAng(),garc.endAng())
        print(garc2.center(),garc2.radius(),garc2.startAng(),garc2.endAng())

    except Exception as err:
        traceback.print_exception(err)

 

(-119.99999999999990,50.00000000000000,0.00000000000000) 129.99999999999991 0.0 0.7895822393995233
(-119.99999999999990,50.00000000000000,0.00000000000000) 129.99999999999991 2.746801533890032 3.536383773289555

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 16 of 18

daniel_cadext
Advisor
Advisor

kinda seems like a bug?

 

 

import traceback
from pyrx_imp import Ap, Db, Ed, Ge, Gi, Gs, Rx

def PyRxCmd_doit():
    try:
        db = Db.curDb()
        ps, pnt1 = Ed.Editor.getPoint("\nFirst")
        ps, pnt3 = Ed.Editor.getPoint("\nSecond")
        ps, rad = Ed.Editor.getDouble("\nRadius")
        pnt2 = pnt1 + ((pnt3 - pnt1) * 0.5)
        pnt2 = pnt2 + (Ge.Vector3d.kXAxis * rad)

        garc = Ge.CircArc3d(pnt1,pnt2,pnt3)
        crv =  Db.Core.convertGelibCurveToAcDbCurve(garc)
        garc2 =  Ge.CircArc3d.cast(Db.Core.convertAcDbCurveToGelibCurve(crv))
        
        print(garc.center(),garc.radius(),garc.startAng(),garc.endAng())
        print(garc2.center(),garc2.radius(),garc2.startAng(),garc2.endAng())

    except Exception as err:
        traceback.print_exception(err)

 

(-120.00000000000004,49.99999999999999,0.00000000000000) 130.00000000000003 0.0 0.789582239399523
(-120.00000000000004,49.99999999999999,0.00000000000000) 130.00000000000003 5.8883941874798245 6.677976426879347

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes
Message 17 of 18

ynapeu
Advocate
Advocate

Hello, you can use getSamplePoints.

 

0 Likes
Message 18 of 18

1127204185
Advocate
Advocate
    AcDbArc(const AcGePoint3d& center, double radius,
            double startAngle, double endAngle);
    AcDbArc(const AcGePoint3d& center, const AcGeVector3d& normal,
            double radius, double startAngle, double endAngle);

Are there only these two ways to achieve it?

0 Likes