How I can get spatial coordinate of a group?

There is a video with an animation on youtube which one perfomed in Sketchup by Ruby. Here Link

I want to do same animation and i used cosinus function. But unfortunately i have not any idea how a can get spatial coordinates of $grp_main for using in cosinus function.

$mod = Sketchup.active_model # Open model
$ent = $mod.entities # All entities in model
$sel = $mod.selection # Current selection
$grp_main = $ent.add_group
$view = $mod.active_view

$s = 100.inch
$w = 60.inch
$beta = 0.0085

def build_material()
  n = 10
  (0..n-1).each { |i|
    (0..n-1).each { |j|
      pts = []
      pts[0] = [i$s,j$s,0]
      pts[1] = [i$s,j$s+$w,0]
      pts[2] = [i$s+$w,j$s+$w,0]
      pts[3] = [i$s+$w,j$s,0]
      entities2 = $grp_main.entities
      face = entities2.add_face pts
      face.back_material = [200,(255/(n)j).round,(255/(n)i).round]
      face.pushpull -40

def scale_object()
  (0..9).each { |i|
      (0..9).each { |j|
        height = Math.cos($beta((ii)+(jj)))2
        scale_transformation = Geom::Transformation.scaling(1,1,height)
        $grp_main.transformation = scale_transformation
        sleep 0.1


I don’t know anything about Ruby, but maybe this’ll help…

  • No (!), Ruby is not PHP. Reference names starting with a $ create global variables, which are forbidden in shared environments like SketchUp. Please assume the habit to use a local variable mod, or for reuse between functions (within a module/class namespace) a module variable @mod.

  • Have you actually tested your code line by line? You can even test line by line when you write a function or a loop. Write in the Ruby Console:

    i = 0
    j = 0

    This syntax does not make sense to the Ruby interpreter, because it cannot tell where to split both names and it does not know what operation to do with them. It is like concatenating two local variables i and s and expecting the interpreter knows that is is not another third variable name. What operation should a zero-width gap between two variables be? If you need multiplication, use the multiplication operator *.

  • The functions build_material and scale_object should not access anything from the environment outside the function definitions, because they do not know whether it is there. You should pass all needed data as parameters. The function signature (function name and paramters) is like a contract the tells the programmer (you) what the function needs, and it guarantees to the Ruby interpreter that all needed data is available.

    Please rewrite the function as def build_material(grp_main, s, w) and def scale_object(grp_main, view, beta).

A group contains usually many entities and extends in space, so there are many possible coordinates you might want. In fact a group creates a local coordinate system whose origin is positioned somewhere in the model. You can get the origin with grp_main.transformation.origin.


Prefer view.invalidate over view.refresh. Use view.refresh if you know you really really need it.

Also, sleep is not ideal. It blocks SketchUp. A timer would be better (UI.start_timer; Module: UI — SketchUp Ruby API Documentation ), but in this case using the Animation interface is best: Class: Sketchup::Animation — SketchUp Ruby API Documentation

1 Like