#draw_(ugly)points >> #draw_fancy_point if #on_mouse_not_move; "Study"

I had some spare time to learn Ruby, but get bored … (you know my old “subject” oriented, “Commodore 64 Basic” brain can’t easily get this “super” “inheriting” “subclass” and so on…)

So, I’ve get some fun instead, I thought I’d share this:

#Just for fun...(?) ;-)
class MyFancyPointsStudy
  def initialize(ani_start_size = 48, pointsize = 24, segments = 12, pointcolor = "DodgerBlue")
      @ip1 = nil
      @ani_start_size = ani_start_size
      @pointsize = pointsize
      @pointcolor =  pointcolor
      @segments = segments
  def activate
      @ip1 = Sketchup::InputPoint.new
      @ip = Sketchup::InputPoint.new
      @point_to_draw = nil
      @point_ani = nil
  def on_mouse_not_move(view, x, y)
    # Stop the timers, otherwise infinitely run
    UI.stop_timer(@timer_cursor_not_move) if @timer_cursor_not_move
    UI.stop_timer(@timer_ani) if @timer_ani
    @ani_size = @ani_start_size
    to_green_color = 255
    ani_time = 0.05
    #start the animation
    @timer_ani = UI.start_timer(ani_time,true){
      @point_to_draw_ani = @ip1.position
      @ani_size -= 1
      to_green_color -=10 if to_green_color > 20
      @ani_color = [to_green_color,255,0]
      UI.stop_timer(@timer_ani) if @ani_size < @pointsize + 2 
      @point_to_draw_ani = nil if @ani_size < @pointsize + 2
    # Start the timer to display fancy point after some time when animation done
    to_draw_time = 0.2 + ani_time*(@ani_start_size-@pointsize)
    @timer_cursor_not_move = UI.start_timer(to_draw_time, false){
      @point_to_draw = @ip1.position
  def onMouseMove(flags, x, y, view)
    @ip.pick view, x, y
    view.tooltip = @ip.tooltip
    if( @ip == @ip1 )
      on_mouse_not_move(view, x, y) if @ip.degrees_of_freedom == 0
      @ip1.copy! @ip
      UI.stop_timer(@timer_cursor_not_move) if @timer_cursor_not_move
      UI.stop_timer(@timer_ani) if @timer_ani
      @point_to_draw_ani = nil
  def draw(view)
    # @ip1.draw(view) if @ip1 && @ip1.display?
    view.draw_points((@ip.position), 6, 3, "red" ) if @point_to_draw
    draw_fancy_point(@point_to_draw_ani, view, @ani_size, @segments, @ani_color, false) if @point_to_draw_ani
    draw_fancy_point(@point_to_draw, view, @pointsize, @segments, @pointcolor, true) if @point_to_draw 
  def draw_fancy_point( point, view = Sketchup.active_model.active_view, size=12, seg=12, color="black", bg=true )
    # may have to define some limits, just in case:
    # size = 3 if size < 3
    # seg = 3 if seg < 3
    # seg = 24 if seg > 24
    # Fancy point outer radius, to create a little white padding around
    radius0 = view.pixels_to_model((size+2)/2, point)
    # Fancy point "real" radius, the line width taken into consideration (more or less)
    radius1 = view.pixels_to_model((size-2)/2, point)
    # Fancy point inner transparent 'circle'
    radius2 = view.pixels_to_model((size-4)/2, point)
    #angle to make the polygon vertices's of fancy point, according the segments number
    angle = (360/seg).degrees
    # The fancy point will be 2D, but should be facing to camera direction...
    vec_ax = view.camera.direction
    # ... by using axes transformation (arbitrary axes created from camera direction as z axis)
    tr_ax = Geom::Transformation.axes(point, vec_ax.axes[0], vec_ax.axes[1], vec_ax.axes[2])

    # Creating two set of point <arrays> , considering above mentioned transformation
    #   by using offset and rotation transformation
    pt0z = []
    pt1z = []
    pt2z = []
    pt0z[0] = point.offset(X_AXIS.transform(tr_ax), radius0)
    pt1z[0] = point.offset(X_AXIS.transform(tr_ax), radius1)
    pt2z[0] = point.offset(X_AXIS.transform(tr_ax), radius2)
    tr_z = Geom::Transformation.rotation(point,Z_AXIS.transform(tr_ax),angle)
    for i in 1..seg-1
      pt0z[i] = pt0z[i-1].transform(tr_z)
      pt1z[i] = pt1z[i-1].transform(tr_z)
      pt2z[i] = pt2z[i-1].transform(tr_z)
    # Creating half transparent white background inside
    view.drawing_color = [255,255,255,128]
    view.line_width = 1
    view.draw(GL_POLYGON, pt2z) if bg
    # Creating the "normal" and (ugly) rectangle point in the middle
    view.draw_points( point, 2, 2, color)
    # Creating the dotted always visible contour (2D or screen space) 
    #   so this will sown even behind other objects (e.g. face)
    #   used for animation too
    view.drawing_color = color
    view.line_width = 1
    view.line_stipple = "_" ## BTW. Can I scale 'length' of dots or dashes?
    view.draw2d(GL_LINE_LOOP, pt1z.map{|p| view.screen_coords( p )})
    # Guess what it is for...
    view.drawing_color = color
    view.line_width = 3
    view.line_stipple = ""
    view.draw(GL_LINE_LOOP, pt1z) if bg
    # The white padding
    view.drawing_color = "white"
    view.line_width = 1
    view.line_stipple = ""
    view.draw(GL_LINE_LOOP, pt0z) if bg
Sketchup.active_model.select_tool( MyFancyPointsStudy.new(48,12,24, "dodgerblue") )

Enjoy! Or whatever… :beers:


:mage: @ani_timer reminds me of https://vimeo.com/68927967 (https://git.io/fhNcB)


Yea, that one a little more complex… Thanks!

When used as a library function not much complex :wink:

1 Like

Do you have a github account that you add these things too? Would be easier to find in the long run. Forum threads tends to get buried.

If anyone asks about something like this it would be nice to have an easy to way point to updated information/example.

1 Like

No, I have no github account. Currently I’m not really familiar all the terms and wordings on it.
Perhaps, later on I will have got some more time to look at how to use it . :blush:
Thanks for suggestion! :+1:t4:

" I’m not a programmer or 3D designer, just like to discover Ruby & SketchUp."

1 Like

In that regards, you are right. But usually first I would like to understand, what I willing to use… :grinning:

Just ask if you got questions. And thanks for sharing!

1 Like

Awesome @Aerilius :heart_eyes: