Sine wave disc formula?

Some additional observations …

Regarding these two lines:

vector = Geom::Vector3d.new(0, 0, 1)
vector2 = vector.normalize!

“vector” is already normalized if you always use “(0,0,1)” … “vector2” doesn’t really seem to be necessary as you could use “vector” instead. If you use something like (1,1,1), then “vector.normalize!” is all that’s needed. BTW, when using this vector to create the “add_circle”, it shouldn’t care whether the normal vector is normalized or not.

Within the loop, these two lines:

vec2 = vert_pos
ang = vec1.angle_between vec2

can be replaced by:

ang = vec1.angle_between vert_pos

since “vert_pos” can be interpreted as a vector instead of a co-ordinate.

Actually you only use vector and vector2 to set a normal for the circle creation, so no need to have either of those set up, just replace it with the standard Constant Z_AXIS in the circle code, e.g.

edges = circle_gents.add_circle(centerpoint, Z_AXIS, radius, segments)

Note that it is normalized as [0,0,1], BUT there is no need to normalize a vector when it’s used for such an axis definition…

It’s also best to parenthesize arguments, so:

ang = vec1.angle_between(vert_pos)

etc etc…

1 Like

good points, that .normalize! is pirated straight from the API, which we know should be taken with a grain of salt…

hi @TIG, did you find the latest rbz at SCF?

any other things that might break earlier versions?

dave’s trying to make sea sick…

EDIT: I’ll add the code here for ease of reference…

I may as well use ORIGIN for the circle and X_AXIS for ang = vert1 as well…

# based on JF.draw_sine_wave by Jim Folts, with help from Jim Hamilton
module JcB
  module SineCircle
    extend self

    @radius = 0.5.m
    @segments = 96
    @modulo = 6
    @scale = 4
    @keep_circle = 'Yes'
    @cylinder = 'Yes'
    @explode = 'Yes'

    def single_wave
      model = Sketchup.active_model
      entities = model.active_entities

      prompts = [' Circle @radius? ', ' Circle Segments? ', ' Wave Segments? ', ' Wave Height? ',
                 ' keep Circle ', ' keep Cylinder ', 'Explode All? ']
      defaults = [@radius, @segments, @modulo, @scale, @keep_circle, @cylinder, @explode]
      list = ['', '', '', '1|2|3|4|5|6|7|8|9', 'No|Yes', 'No|Yes', 'No|Yes']

      input = UI.inputbox(prompts, defaults, list, 'Sine Circle Details')
      return unless input

      @radius = input[0].to_l
      @segments = input[1].to_i
      @modulo = input[2].to_i
      @scale = input[3].to_i
      @keep_circle = input[4]
      @cylinder = input[5]
      @explode = input[6]

      if @segments.modulo(@modulo) != 0
        UI.messagebox('Use Number of Circle Segments that are divisible by the Number of Wave Segments')
        p 'retry'
        single_wave
      else

        # wrap geometry creation in an undo...
        Sketchup.active_model.start_operation('Sine Circle')
        circle_grp = entities.add_group
        circle_gents = circle_grp.entities
        # create the base circle perpendicular to the normal or Z axis
        edges = circle_gents.add_circle(ORIGIN, Z_AXIS, @radius, @segments)


        # p     edges.first.length.to_mm
        # collect the verts
        verts_ary = []
        edges.first.curve.vertices.each { |vert| verts_ary << vert.position.to_a }

        edges.each(&:find_faces) rescue edges.each{|i| i.find_faces}
        face = circle_gents.grep(Sketchup::Face)[0]
        face.reverse!

        face.pushpull(@radius) if @cylinder == 'Yes'

        unless @keep_circle == 'Yes' || @cylinder == 'Yes'
          entities.erase_entities(circle_grp)
        end
        # p     verts_ary.length

        # add the new vert positions
        i = 0
        new_pts = []
        segs = @segments / 2
        verts_ary.each do |vert_pos|
          i += 1
          ang = X_AXIS.angle_between(vert_pos)
          height = @scale * Math.sin(@modulo * ang)
          if i <= segs # of base circle
            new_pts << (vert_pos[0..1] << height)
          else # flip
            new_pts << (vert_pos[0..1] << -height)
          end
        end

        # make the curve
        grp = Sketchup.active_model.active_entities.add_group
        gents = grp.entities
        gents.add_curve(new_pts)

        if @cylinder == 'Yes'
          point = Geom::Point3d.new(0, 0, @radius / 2)
          t = Geom::Transformation.new point
          grp.move! t
        end

        if @explode == 'Yes'
          grp.explode
          circle_grp.explode unless circle_grp.deleted?
        end

        Sketchup.active_model.commit_operation
      end
    end # def single_wave
  end # module SineCircle
end # module JcB

unless file_loaded? 'sine_circle.rb'
  # create toolbar
  tb = UI::Toolbar.new 'Sine Circle'
  # menu item
  menu = UI.menu('Plugins', 'Sine Circle')

  cmd = UI::Command.new('Sine Circle') { JcB::SineCircle.single_wave }

  cmd.tooltip = cmd.status_bar_text = 'create sine waves on cylinders...'
  cmd.large_icon = cmd.small_icon = File.join(File.dirname(__FILE__), 'sine_circle.png')

  menu.add_item(cmd)
  tb.add_item(cmd)
  # showing the toolbar
  tb.get_last_state == -1 ? tb.show : tb.restore
  file_loaded('sine_circle.rb')
end # unless

john