Finally, fixed
import sys
import clr
import math
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
def isClockwise(arc):
pStart = arc.StartPoint
pCenter = arc.CenterPoint
pEnd = arc.EndPoint
vecta = Vector.ByTwoPoints(pCenter, pStart)
vectb = Vector.ByTwoPoints(pCenter, pEnd)
cp = vecta.Cross(vectb)
return cp.Z < 0
def arcAngle_by_Length(current_arc, need_length):
# arclength = (2 * math.pi * current_arc.Radius) * (current_arc.SweepAngle / 360)
sweepAngle = (need_length * 360) / (2 * math.pi * current_arc.Radius)
return sweepAngle
def offset_Curve_keepLength(input_arc, factor):
global normal_vect
# input arc attribute
lengthArc = input_arc.Length
init_startAngle = input_arc.StartAngle
init_sweepAngle = input_arc.SweepAngle
if isClockwise(input_arc):
input_arc = input_arc.Reverse()
# offset arc
temparc = input_arc.Offset(factor)
try:
radius = temparc.Radius
except:
temparc = temparc.Explode()[0]
radius = temparc.Radius
new_sweepAngle = arcAngle_by_Length(temparc, lengthArc)
offsetAngle = (new_sweepAngle - init_sweepAngle) / 2
newarc = Arc.ByCenterPointRadiusAngle(
input_arc.CenterPoint,
radius,
temparc.StartAngle - offsetAngle,
temparc.StartAngle + new_sweepAngle - offsetAngle,
normal_vect
)
return newarc
input_arc = IN[0]
lstOffset = [0] + IN[1]
len_Bar = IN[2]
margin_overlap = 1 # in meter
normal_vect = Vector.ByCoordinates(0,0,1)
out = []
for d in lstOffset:
temp = []
offset_arc = offset_Curve_keepLength(input_arc, d)
print("offset_arc Length", offset_arc.Length)
start_Angle = offset_arc.StartAngle
end_Angle = offset_arc.StartAngle + offset_arc.SweepAngle
#
perimeter = offset_arc.Radius * 2 * math.pi
temp.append(offset_arc)
a, b = 1, -1
k= 0
#
while k < 500:
k += 1
a, b = b, a # swap each loop
marginAngle = (margin_overlap * 360) / (2 * math.pi * offset_arc.Radius)
# compute the arc remainder
restArc = Arc.ByCenterPointRadiusAngle(offset_arc.CenterPoint, offset_arc.Radius, end_Angle - marginAngle, start_Angle + marginAngle, normal_vect)
if math.ceil(restArc.Length) < len_Bar:
restArc = restArc.Translate(0,0, a * -0.1)
temp.append(restArc)
# remove small curves
temp = [c for c in temp if c.Length > margin_overlap]
out.append(temp)
break
#
# rotate the new arc
offset_arc = offset_arc.Rotate(offset_arc.CenterPoint, Vector.ByCoordinates(0,0,1), offset_arc.SweepAngle - marginAngle)
# add a small vertical offset
offset_arc = offset_arc.Translate(0,0, a * 0.1)
# update end angle
end_Angle = offset_arc.StartAngle + offset_arc.SweepAngle
temp.append(offset_arc)
#
OUT = out
offset curve keep length_v5.dyn (22.9 KB)