Thicker spirals without inner faces?
-
I've started playing with the Ruby api aspect of Sketchup.
I created this script to draw a spiral out of log spiral curves.
module LogSpirals def self.rotate_thing(thing, rotation_angle) rotate_transform = Geom;;Transformation.rotation([0,0,0], [0,0,1], rotation_angle.degrees) thing.transform!(rotate_transform) end def self.make_material(rgb, alpha) model = Sketchup.active_model r, g, b = rgb color = Sketchup;;Color.new(r, g, b) material = model.materials.add("Rainbow Face r #{r} g #{g} b #{b} alpha #{alpha}") material.color = color material.alpha = alpha material end def self.color_face(face, material) face.material = material face.back_material = material end def self.create_spiral(scale_factor, growth_factor, steps, z_offset, thickness, rotation, rgb, alpha) model = Sketchup.active_model entities = model.active_entities model.start_operation("log_spiral",true,false,true) # create a spiral starting at the origin spiral_points = [] (0..steps).each do |angle| theta = angle.degrees r = scale_factor * Math.exp(growth_factor * theta) x = r * Math.cos(theta) y = r * Math.sin(theta) # subtract 10 so the spiral starts at the origin x2 = (x * 100) - 10 y2 = y * 100 point = Geom;;Point3d.new(x2, y2, 0) spiral_points << point end # make a copy of the spiral offset up the z axis by z_offset spiral_points2 = spiral_points.map{ |point| point.offset([0, 0, z_offset]) } material = self.make_material(rgb, alpha) # turn it into a solid with thickness (0...steps).each do |i| pts = [spiral_points[i], spiral_points[i+1], spiral_points2[i+1], spiral_points2[i]] # create a face along the spiral face = entities.add_face(pts) # color the face self.color_face(face, material) # extend the face to have a thickness face.pushpull(thickness) end # create a group out of the spiral spiral_group = entities.add_group(entities.to_a) # rotate the spiral the given degrees self.rotate_thing(spiral_group, rotation) # refresh the view so the spiral is drawn model.active_view.refresh model.commit_operation end end #LogSpirals Module scale_factor = 0.1 growth_factor = 0.4 steps = 360 z_offset = 10 thickness = 0 # 1 2 3 4 5 6 7 8 9 10 11 12 # yellow yellow-g green green-cyan cyan cyan-blue blue mage-blue magenta red-mage red orange # 255,255,0 255,127,0 0,255,0 0,255,127 0,255,255 0,127,255 0,0,255 127,0,255 255,0,255 255,0,127 255,0,0 255,127,0 # 30, 60 90 120 150 180 210 240 270 300 330 360 color_yellow = [255,255,0] color_yellow_green = [127,255,0] color_green = [0,255,0] color_green_cyan = [0,255,127] color_cyan = [0,255,255] color_cyan_blue = [0,127,255] color_blue = [0,0,255] color_magenta_blue = [127,0,255] color_magenta = [255,0,255] color_red_magenta = [255,0,127] color_red = [255,0,0] color_orange = [255,127,0] colors = [color_yellow, color_yellow_green, color_green, color_green_cyan, color_cyan, color_cyan_blue, color_blue, color_magenta_blue, color_magenta, color_red_magenta, color_red, color_orange] angles = [30,60,90,120,150,180,210,240,270,300,330,360] alpha = 0.5 # this doesn't quite work as it keeps duplicating all the work over and over # (0...12).each do |i| # color = colors[i] # angle = angles[i] # spiral = LogSpirals.create_spiral(scale_factor, growth_factor, steps, z_offset, thickness, angle, color, alpha) # end i = 11 rotation = angles[i] color = colors[i] spiral = LogSpirals.create_spiral(scale_factor, growth_factor, steps, z_offset, thickness, rotation, color, alpha)
The first result is ok, but I decided I wanted to have thicker arms to each spiral.
thin spirals: https://drive.google.com/file/d/1sF3KD4oTrsLs0IzA4099fzoaGW2zUzZq/view?usp=drive_link
thicker spirals: https://drive.google.com/file/d/1MS-RIx5OlmCeZwGkQi9QI3zvcOLmS53K/view?usp=drive_link
I sort of solved this by adding a pushpull to each face of the arm, however, this creates a bunch of overlapping and internal faces that are visible in the finished model.
Is there a way to make the arms thicker without all these internal and overlapping faces?
Thanks for any ideas
j_jones -
The method is to draw a single spiral as a group, and then just rotate them and assign them colors, as you do.
However, you need to have
[list][]the start operation outside the loop on spirals
[]the creation of a group at the beginning of the spiral generation method. You basically create the group (group = model.active_entities.add_group
) and create the faces in that group (ee = group.entities
andface = ee.add_face...
.)For thickness, you need first to offset them from the origin. Otherwise, the spirals would collide at origin. You may want to draw a cylinder at origin as the starting point of the spirals. Second, there is no other way than to compute the offset of an individual spiral, which requires a little bit of calculation (there is no API for that unfortnately).
-
@fredo6 said:
The method is to draw a single spiral as a group, and then just rotate them and assign them colors, as you do.
However, you need to have
[list][]the start operation outside the loop on spirals
[]the creation of a group at the beginning of the spiral generation method. You basically create the group (group = model.active_entities.add_group
) and create the faces in that group (ee = group.entities
andface = ee.add_face...
.)For thickness, you need first to offset them from the origin. Otherwise, the spirals would collide at origin. You may want to draw a cylinder at origin as the starting point of the spirals. Second, there is no other way than to compute the offset of an individual spiral, which requires a little bit of calculation (there is no API for that unfortnately).
Thank you this is helpful. I see now how to create a separate group for each spiral, that will help.
As for the thickness issue, I am now trying to build my own box from each face which resulted in a new question!
-
The offset of a set of faces is not equivalent to the individual offset of each face.
You have to make the calculation for the curve. Since your spiral is in 2D, it is not too complex.You either compute the intersection of the offset of each segment, or you take the bissector at each nagle and offset the vertices by the offset value divided by the cosinus of the angle.
Advertisement