Python Rhino: Length Match

November 28, 2011
by admin

    One of the few things our digital fabrication group knew for sure is that the edge of a bounding box was the same length we wanted for the edge of an octagon. At first I thought about being able to select a set of curves and re-creating them into an octagon. This was a nice idea, but when I did some research it turns out Dr. Demaine over at MIT had already written about it, “Polygonization“. The basic idea is that unless you have a triangle, you can create more than one shape with n lengths of x sizes. This doesnt help us as we have been trying to predict geometry. So I decided that the first step would be to at least be able to take a geometry and recreate it as close to an octagon as possible. I decided that if we were going to try and describe these odd lengths, it would probably be in a shape most resembling an octagon. This set me off on a direction to create a script that takes an input set of curves, and applies those lengths to an output set of curves. For this project is octagons, with 8 sides, it automatically iterates through 8 sides. This could obviously be changed using a user input, but for speed of this test it takes to long for the user to select “8” every time. First I create an array of integers (this was prior to me figuring out dynamic lists), and declare the sides of my polgyon.

    #First step getting by user, later needs to be automated
    new_curve=[0,0,0,0,0,0,0,0,0]
    origin_curve=[0,0,0,0,0,0,0,0,0]
    poly_sides=8
    

    Then I take the polygon and explode it into an array. The for loop following re-distributes the curves into a new array. I forgot why this happens, it might have something to do with how the array was originally indexed, or I planned on changing it later, either way its there and it does it:

    box_poly_array=rs.ExplodeCurves(box_poly, True)
    flat_poly_array=rs.ExplodeCurves(flat_poly, True)
    
    for i in range(poly_sides):
        origin_curve[i]=box_poly_array[i]
        new_curve[i]=flat_poly_array[i]
    

    The last step is to iterate through the sides and apply the transformation to each one. I get the length of each curve from their corresponding index. Next I get the midpoint of the curve I want to change. The scale_factor divides the old and new curve to get the difference and then using rhinos internal XformScale I apply the scale to the new curve.

    #Make corresponding lengths match
    import rhinoscriptsyntax as rs
    
    #First step getting by user, later needs to be automated
    new_curve=[0,0,0,0,0,0,0,0,0]
    origin_curve=[0,0,0,0,0,0,0,0,0]
    poly_sides=8
    
    #Index Polygons
    box_poly=rs.GetObject("Select Bounded Polygon")
    flat_poly=rs.GetObject("Select Flat Polygon")
    
    box_poly_array=rs.ExplodeCurves(box_poly, True)
    flat_poly_array=rs.ExplodeCurves(flat_poly, True)
    
    for i in range(poly_sides):
        origin_curve[i]=box_poly_array[i]
        new_curve[i]=flat_poly_array[i]
    
    for i in range(poly_sides):
        new_curve_len=rs.CurveLength(new_curve[i])
        origin_curve_len=rs.CurveLength(origin_curve[i])
        
        new_curve_mid=rs.CurveMidPoint(new_curve[i])
        scale_factor=origin_curve_len/new_curve_len
    
        curve_scale=rs.XformScale(scale_factor,new_curve_mid)
        old_curve=new_curve[i]
        new_curve[i]=rs.TransformObject(new_curve[i], curve_scale, True)
        rs.DeleteObject(old_curve)
    
    

    Leave a Comment