Python Rhino: Length Match
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)