Hello,
I'd like to fillet an edge loop for a Polygon ObjectData plugin I am making (like the Fillet option in the native Polygon Object primitives). I am seeking help in getting the start & end angle of the bevel to work correctly.
So far in my research, it appears to be a matter of mathematically generating an arc of points between two points [V2, V3] based on their distance from a third angular point [V1] and a radius.
I'd like to get this result (sorry, I have B & C swapped in my scene example):
I am not sure how I should limit the radius size or to get the correct arc direction for the arc & arc points. Here are my current code & scene file:
import c4d,math,random
global C,startAngle,endAngle,radius,subdivisions
v1Obj = doc.SearchObject("V1")
v2Obj = doc.SearchObject("V2")
v3Obj = doc.SearchObject("V3")
aObj = doc.SearchObject("A")
bObj = doc.SearchObject("B")
cObj = doc.SearchObject("C")
archB = doc.SearchObject("Arc B")
obj0 = doc.SearchObject("0")
obj1 = doc.SearchObject("1")
obj2 = doc.SearchObject("2")
obj3 = doc.SearchObject("3")
txt = doc.SearchObject("Text")
def GetPointsOfArc():
global C,startAngle,endAngle
FullCircleAngle = 2 * math.pi
normalizedEndAngle = None
if startAngle < endAngle:
normalizedEndAngle = endAngle
else:
normalizedEndAngle = endAngle + FullCircleAngle
angleRange = normalizedEndAngle - startAngle
angleRange = FullCircleAngle if angleRange > FullCircleAngle else angleRange
step = angleRange / subdivisions
currentAngle = startAngle
while (currentAngle <= normalizedEndAngle):
arcPt = c4d.Vector()
arcPt.x = C.x + radius * math.cos(currentAngle)
arcPt.y = C.y + radius * math.sin(currentAngle)
yield arcPt
currentAngle += step;
archB[c4d.PRIM_ARC_START] = startAngle
archB[c4d.PRIM_ARC_END] = endAngle
degStartAngle = c4d.utils.Deg(startAngle)
degEndAngle = c4d.utils.RadToDeg(endAngle)
print("*"*50)
print("startAngle: %s°\nendAngle: %s°\n"\
"angleRange: %s°\nnormalizedEndAngle: %s°"%(round(degStartAngle),
round(degEndAngle),round(angleRange,2),round(normalizedEndAngle,2)))
def draw(bd):
points = GetPointsOfArc()
COLOR_SPHERE = c4d.Vector(0, 1.0, 0)
for pt in points:
bd.DrawSphere(pt, c4d.Vector(4.0), COLOR_SPHERE, c4d.NOCLIP_Z)
def main():
global C,startAngle,endAngle,radius,subdivisions
radius = op[c4d.ID_USERDATA,2]
subdivisions = op[c4d.ID_USERDATA,3]
V1 = v1Obj.GetAbsPos()
V2 = v2Obj.GetAbsPos()
V3 = v3Obj.GetAbsPos()
a = V2-V1
b = V2-V3
a.Normalize()
b.Normalize()
halfang = math.acos((a.Dot(b)))/2
ab = (a+b)/2
ab.Normalize()
C = V2 - radius/math.sin(halfang)*ab
A = V2 - radius/math.tan(halfang)*a
B = V2 - radius/math.tan(halfang)*b
aObj.SetAbsPos(A)
bObj.SetAbsPos(B)
cObj.SetAbsPos(C)
startAngle = math.atan2(A.y - C.y, A.x - C.x);
endAngle = math.atan2(B.y - C.y, B.x - C.x);
SCENE FILE: Bevel.c4d
I pieced a lot of the math code together from online resources, so I don't entirely understand it. Currently, the arc points are sweeping in the wrong direction. When the startAngle is negative, both the arc & arc points are incorrect. When both the startAngle & endAngle are negative, however, both are correct.
Can anyone provide guidance for getting the arc & arc points to go in the correct direction in these cases please? Thank you!