0
$\begingroup$

Following the instructions from this post on Stack Overflow, I have been able to find points A, B, and C from points V1, V2, and V3 and a radius value (code below). I would like to be able to find a specified number of subdivisions for the arc section labeled 'Arc B.' Can anyone help me find these position values of these points please?

Finding Start and End Angles

    r = 106 #radius
    V1 = Vector(50, 100, 0)
    V2 = Vector(100, 300, 0)
    V3 = Vector(350, 350, 0)
    a = V2-V1
    b = V2-V3
    a.Normalize()
    b.Normalize()
    halfang = math.acos((a.Dot(b)))/2
    ab = (a+b)/2
    ab.Normalize()
    A = V2 - r/math.tan(halfang)*a
    B = V2 - r/math.tan(halfang)*b
    C = V2 - r/math.sin(halfang)*ab

$\endgroup$
1

2 Answers 2

0
$\begingroup$

One very simple way to do it is to just find the straight line distance between the points A and C. Divide that distance by the number of points you want to subdivide+1. Then starting at A moving along the line formed between A and C add that distance for each subdivision. This gives a nice even subdivision without having to argue with PI.

To get the point on the circle, just take the normalized vector between B and your new point and multiply it by the radius of the circle. The result is a subdivision point on your circle/sphere.

float distanceAC = length(C-A);
float stepLength = distanceAC/(SubdivisionsCount+1); // 4 in this case
vector v = C-A; // gives a vector pointing from A to C
v = normalize(v);
for( int i=1; i<SubdivisionCount+1; i++ ){
     point pointOnLine = A + v*i*stepLength; // Need steplength*i steps along v
     point subdivisionLocation = normalize(pointOnLine-B)*radius;
     // save the subdivision location
}

This has the plus of being simple, but the negative is that if you want to do to many steps or you want your steps to be extremely accurate, or you want to subdivide over a very large arc, then accuracy suffers.

$\endgroup$
0
$\begingroup$

Thank you for the responses! This solution using quadratic bezier interpolation wound up working for me.

def ArcPoints(node):
    points = node.GetAllPoints()
    if len(points) < 3:
        return

    # The first three points of the point object.
    a, b, c = points[:3]

    samples = 6
    arcPoints = list()
    for i in range(samples):
        t = float(i)/(samples - 1)
        # The quadratic bezier interpolation at t.
        p = a * (1-t) ** 2 + b * 2 * (1-t) * t + c * t ** 2
        arcPoints.append(p)

    return arcPoints
$\endgroup$
3
  • $\begingroup$ This quadratic Bezier curve will not exactly reproduce a circular arc, but only approximate it. To truly represent a circular arch you should use a rational quadratic Bezier curve. $\endgroup$
    – Reynolds
    Commented Oct 16, 2020 at 23:11
  • $\begingroup$ @Reynolds Thank you for the reply. How would I do that with three points and an equation in Python? $\endgroup$ Commented Oct 16, 2020 at 23:14
  • $\begingroup$ @Reynolds, I found this equation CurvePoint = (A*W1*(1-t)^2 + B*W2*2t(1-t) + C*W3*t^2) / (W1*(1-t)^2 + W2*2t(1-t) + W3*t^2) My Python interpretation is: p = (a * w1 * (1-t) ** 2 + b * w2 * 2*t (1-t) + C * w3 * t ** 2 ) / (w1 * (1-t) ** 2 + w2 * 2*t (1-t) + w3 * t**2) Would 2t be 2*t? Do I have the rest correct? Also, what would the weights (w values) be for a circular arc? Thank you. $\endgroup$ Commented Oct 16, 2020 at 23:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.