Rounding curve length issue

Hi all, @c.poupin @jacob.small

In my revit model attached below, I fixed all parameters as shown in the image below in order to get exactly 2 overlaped bar with 12m length for each (the rebar bar type choosen in the example is HA14 (FE400)), but my code not works correctely due to the wrong rounding of the curve circumference computed by python!!

How to fix this issue ?

Please check my refrences below
Shaft1.rfa.rvt (7.4 MB)

circular_overlap_curves.dyn (23.5 KB)

Thanks.

From your script circular_bar_type.GetParameterValueByName("Diamètre de barre")
I would suggest using the built in parameters or attributes to get values as this will allow your code to work with different languages - for example see below

EDIT See correction below
Formula for the radius of the bars with 50 * diameter overlap is r = (length - dia * 100) / π because the overlap is at both ends - so the angle in radians is π + 2θ with θ = 50 * dia / r

For a 12 metre 14mm dia bar the radius would be 3.775m and the circumference 23.720m

I actually think the issue is that the value of the bar diameter is in Revit Internal Units so you need to convert. Further I would not do any rounding until the final output

bartype = UnwrapElement(IN[0])
conv = lambda l: UnitUtils.ConvertFromInternalUnits(l, UnitTypeId.Meters)

OUT = conv(bartype.BarModelDiameter), bartype.BarNominalDiameter

image

1 Like

Dynamo does the unit conversion - so that should be fine

1 Like

The object in your model has an outer radius of 3.657m, less the 57mm offset for rebar cover → r = 3.6m so 2πr = 22.619

1 Like

Thanks for your replys @Mike.Buttery

Effectively, I discovered this error, and I was initially wrong to compute the right cover which should equal to 57mm as you mentionned in the case where the bar diameter = 14 mm according to this relation:

cir_cover = cover + circular_bar_type.GetParameterValueByName("Diamètre de barre")/2000

I tried various bar diameter to test the code and it works and I get 2 x 12.

image

I wanted to make change to the cover relation according to the following relation, but in this case it does not works and I’ve again a rounding issue

cir_cover = cover - circular_bar_type.GetParameterValueByName("Diamètre de barre")/2000

I’ll take your suggtion in consideration

1 Like

I did not allow that the overlaps are symmetrical across the centre of the circle… so formula is now r = (length - 50 * dia) / π so now r = (12 - 50 * 0.014) / π = 3.5969m and the circumference is 22.6m.

The simplified formula for the circumference so you can check calculations would be C = 24 - 100 * dia

1 Like

@Mike.Buttery

maybe you didn’t well understand me!!..my rebar circumference is obtained by offseting the outer face of the model by the cover which was initially compueted by this formula and the code works after corrections I made as I said above:

cir_cover = cover + circular_bar_type.GetParameterValueByName("Diamètre de barre")/2000

Now, I want to compute the cover by this formula and does it not works as I explain above:

cir_cover = cover - circular_bar_type.GetParameterValueByName("Diamètre de barre")/2000

I use the same formula for the circumference calculation…Indeed the script that I attached above is a particular case of my main code where I want to check the condition C = 24 - 100 x diam that gives (2 x 12m)…the main goal of the code is to compute the number of rebar of 12 m and the remaining length along the circumference whatever the radius of the model.
be kind to check below the main code and the script for creating the model:

main code
import sys
import clr
import math
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitNodes')
import Revit
from Revit.Elements import Element

element = IN[0]
cover = IN[1]
circular_bar_type = IN[2]
vertical_bar_type = IN[3]
H_s = IN[4]
V_s = IN[5]

geo = element.Geometry()
surfaces = geo[0].Explode()

s_area = []

for i in surfaces:
    s_area.append(i.Area)
    
S_area = ["%0.2f"%(round(i,2)) for i in s_area]
    
surf = []
surf_area = set()

for s, a in zip(surfaces, S_area):
    if a not in surf_area and S_area.count(a) == 2:
        surf.append(s)
        surf_area.add(a)
        
#getting circular curves        
out_cir_crv = surf[1].GetIsoline(1, 0).Explode()[0]


#getting vertical curves
out_V_crv = surf[1].GetIsoline(0, 1).Explode()[0]


# overlap lengths
circ_overlap_length = circular_bar_type.GetParameterValueByName("Diamètre de barre")*50/1000
V_overlap_length = vertical_bar_type.GetParameterValueByName("Diamètre de barre")*50/1000

# cover from side face to circular rebar centerline
cir_cover = cover - circular_bar_type.GetParameterValueByName("Diamètre de barre")/2000 

# cover from side face to vertical rebar centerline
V_cover = 2* cir_cover-cover + V_overlap_length/100

# circular curves for outer side
out_cir_crv = out_cir_crv.Offset(-cir_cover)
out_cir_crv = out_cir_crv.Translate(0, 0, cover + 1.5 * V_overlap_length/50 + vertical_bar_type.GetParameterValueByName("Diamètre de cintrage de crochet standard")/2000)

#out_arc_length = round(out_cir_crv.Length, 2)
out_arc_length = out_cir_crv.Length

# total circular rebars length for outer and inner sides
out_circ_path = round(out_cir_crv.Length + circ_overlap_length, 2 )

# circular rebars count for outer side
out_Arc = []
Pt1 = out_cir_crv.StartPoint
Pt2 = out_cir_crv.PointAtSegmentLength(6.00)
Pt3 = out_cir_crv.PointAtSegmentLength(12.00)
outer_arc = Arc.ByThreePoints(Pt1, Pt2, Pt3)
star_angle = outer_arc.StartAngle
end_angle = outer_arc.SweepAngle
out_circ_overlap_angle = circ_overlap_length * 360 / out_arc_length


if out_cir_crv.Length <= 12.00:
    out_Arc.append(out_circ_path)
elif round(out_cir_crv.Length, 2) == round(2 *(outer_arc.Length - circ_overlap_length), 2):
    out_arc1 = Arc.ByCenterPointRadiusAngle(out_cir_crv.CenterPoint, out_cir_crv.Radius, star_angle, end_angle, Vector.ZAxis())
    out_arc2 = out_arc1.Rotate(out_cir_crv.CenterPoint, Vector.ZAxis(), out_arc1.SweepAngle - out_circ_overlap_angle)
    out_Arc.append(out_arc1.Length)
    out_Arc.append(out_arc2.Length)    
else:
    out_rebar_count = math.ceil(out_circ_path / (12.00 - circ_overlap_length))
    for i in range (0,int(out_rebar_count)):
        star_angle = i * end_angle - i* out_circ_overlap_angle
        End_angle = end_angle + i * (end_angle - out_circ_overlap_angle)
        out_arc = Arc.ByCenterPointRadiusAngle(out_cir_crv.CenterPoint, out_cir_crv.Radius, star_angle, End_angle, Vector.ZAxis())
        if End_angle > 360:
            End_angle = out_circ_overlap_angle
            out_arc = Arc.ByCenterPointRadiusAngle(out_cir_crv.CenterPoint, out_cir_crv.Radius, star_angle, End_angle, Vector.ZAxis())
        out_Arc.append(out_arc.Length)


OUT = out_Arc

Fut_python_rvt_23.dyn (34.5 KB)

Thanks.

I’ve modified your original code and added in a few debug points to the output - there does not seem to be an error that I can find. Can you work back through your code from the output and test each time the radius / circumference is modified to see where the error is being created

image

1 Like

@Mike.Buttery

Sorry; I dont understand well what are you traying to do (can you precise which rebar diameter is used in each case you output?)
for example: in the case of bar diameter = 14mm, rebar circumference C1 = 22.60m so radius = 3.5969m and Shaft radius = 3.5969 + 0.05 = 3.6469m (cover = 0.05 m) so shaft circumference C2 = 22.9141m.

Thanks.

25mm Rebar, Shaft radius 3.6569m, Cover 50 - 12.5 = 37.5mm

When code is not working as expected you debug by stepping through the actions to find where the error is. This can be done by collecting the result at certain points as I have done above. You can also comment out lines and then un-comment one by one to see where errors occur. I will leave that up to you

1 Like

@Mike.Buttery

Sorry, I was wrong in the new cover relation and I mislead you!!!..as shown in the output below; cir_cover = cover = 50 mm, we dont need to abstract the value (bar diameter / 2) from the cover (50 mm) where the cover is computed from the shaft outside face to the bar axis as indicated in the image and the code works now.

here is the updated code and sorry again

updated code
import sys
import clr
import math
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitNodes')
import Revit
from Revit.Elements import Element

element = IN[0]
cover = IN[1]
circular_bar_type = IN[2]
vertical_bar_type = IN[3]
H_s = IN[4]
V_s = IN[5]

geo = element.Geometry()
surfaces = geo[0].Explode()

s_area = []

for i in surfaces:
    s_area.append(i.Area)
    
S_area = ["%0.2f"%(round(i,2)) for i in s_area]
    
surf = []
surf_area = set()

for s, a in zip(surfaces, S_area):
    if a not in surf_area and S_area.count(a) == 2:
        surf.append(s)
        surf_area.add(a)
        
out = ["Shaft radius"]        
#getting circular curves        
out_cir_crv = surf[1].GetIsoline(1, 0).Explode()[0]
out.append(out_cir_crv.Radius)
out.append("Shaft circumference")
out.append(out_cir_crv.Length)
#getting vertical curves
out_V_crv = surf[1].GetIsoline(0, 1).Explode()[0]
out.append("bar diameter")
out.append(circular_bar_type.GetParameterValueByName("Diamètre de barre"))

# overlap lengths
circ_overlap_length = circular_bar_type.GetParameterValueByName("Diamètre de barre")*50/1000
V_overlap_length = vertical_bar_type.GetParameterValueByName("Diamètre de barre")*50/1000
out.append("cir_cover = cover")
# cover from side face to circular rebar centerline
cir_cover = cover
out.append(cir_cover)
# cover from side face to vertical rebar centerline
V_cover = 2* cir_cover-cover + V_overlap_length/100

# circular curves for outer sides
out.append("rebar circumference")
out_cir_crv = out_cir_crv.Offset(-cir_cover)
out.append(out_cir_crv.Length)
out_cir_crv = out_cir_crv.Translate(0, 0, cover + 1.5 * V_overlap_length/50 + vertical_bar_type.GetParameterValueByName("Diamètre de cintrage de crochet standard")/2000)
out_arc_length = out_cir_crv.Length
out.append("rebar radius")
out.append(out_cir_crv.Radius)


# total circular rebars length for outer sides
out_circ_path = round(out_cir_crv.Length + circ_overlap_length, 2 )

out_Arc = []

Pt1 = out_cir_crv.StartPoint
Pt2 = out_cir_crv.PointAtSegmentLength(6.00)
Pt3 = out_cir_crv.PointAtSegmentLength(12.00)
outer_arc = Arc.ByThreePoints(Pt1, Pt2, Pt3)
star_angle = outer_arc.StartAngle
end_angle = outer_arc.SweepAngle
out_circ_overlap_angle = circ_overlap_length * 360 / out_arc_length

if out_cir_crv.Length <= 12.00:
    out_Arc.append(out_circ_path)
elif round(out_cir_crv.Length, 2) == round(2 *(outer_arc.Length - circ_overlap_length), 2):
    out_arc1 = Arc.ByCenterPointRadiusAngle(out_cir_crv.CenterPoint, out_cir_crv.Radius, star_angle, end_angle, Vector.ZAxis())
    out_arc2 = out_arc1.Rotate(out_cir_crv.CenterPoint, Vector.ZAxis(), out_arc1.SweepAngle - out_circ_overlap_angle)
    out_Arc.append(out_arc1.Length)
    out_Arc.append(out_arc2.Length)
    
    

OUT = out, out_Arc

Thanks.