A large home for a prosperous owner, this four-square sports a ground-floor addition (possibly an original feature?) in the kitchen/dining area topped by a bay window, likely in the master suite.
What really catches the eye, however, are the ionic columns around the front porch. (Actually, Tuscan columns with ionic capitals, as Greek columns would have been fluted.)
In contrast to the columns, the upper panes of the dormer windows are a diamond-shaped Tudor style.
Warwick, NY, c. 1920.
Chapter 15—Animation with the Transformation Matrix
Animation! Here we'll take SketchUp into the fourth dimension: time. We'll put components into motion. You will never again see SketchUp as just a 3D tool.
Uh, oh. The transformation matrix. If you think that sounds complicated, you are right. It is complicated. Fortunately, the SketchUp engineers have programmed all the complicated stuff and given us an API that couldn't be much easier to use. Here I'll give you the basics.
How does it do all this? See Appendix T. That was originally slated for the beginning of this chapter as the Google docs somewhat unhelpfully state, "Use of the transformation class requires a knowledge of geometrical transformations in 3 dimensions which is covered extensively on the Internet."
Happily, I found that the use of the Transformation class requires no such knowledge. It just requires one little factoid: the r,g,b coordinates of the instance are found at locations 12, 13 and 14 of the matrix. You can go to Appendix T now if you're afraid you might miss something. We'll wait for you.
martins_sketch_talk.rbhas sprouted lots of new functions and classes. I hope you can say the same for
your_sketch_talk.rb. Here I'll mention two: the circle function and the Column class. Before we get to them let me mention (but not provide a link!) the download package.
The Tutorial Companion Package includes an updated sketch_talk.rb. The classes are now in sketch_talk_classes.rb. (When your source code file starts to get large, it starts to get inconvenient. Two smaller files can be much handier.) It also includes updated documentation including all the new commands. You can download the new docs without the code. (Extract these files—one HTML and three graphics—to any convenient directory. Open the HTML in any convenient browser.)
I'll provide a link to the full package at the end of this chapter. At this point it would be good to split your own
your_sketch_talk.rb into functions and classes. My functions
load 'sketch_talk_classes.rb'. In finished code you should
load. During development that doesn't work. You improve your classes, and reload
your_sketch_talk.rb. It sees
require and does not load the improved classes. Make a note in the code to switch later.
The new API you need for a circle is the
add_circle(). Its arguments are:
That normal? It's just like a face's normal. Here's a support function that I've added, which may explain it.
def make_normal( plane_or_normal ) if plane_or_normal.is_a?( String ) case plane_or_normal when 'rg' then normal = [0,0,1] when 'rb' then normal = [0,1,0] when 'gb' then normal = [1,0,0] else raise "Plane must be 'rg', 'rb', 'gb' or a normal vector." end else normal = plane_or_normal end return normal end # of make_normal()
col()command in SketchUp. It's first four arguments are the circle. The last is the PushPull distance.
Yes, the tower leans just under four meters. (The Pisans are working on it. It used to lean more than five meters.)
On to more API. The
Entities.add_circle() method returns an array of edges: the edges that make up the circle. You need these as adding a circle does not add a face. (Do you think it should? I think it should. Adding coplanar edges that bound a face should add a face, to be consistent.) You have to add the face:
def draw( ents ) @group = ents.add_group() ents = @group.entities() @edges = ents.add_circle( @center, @normal, @radius, @nsides ) @face = ents.add_face( @edges ) orient( @face ) ents.add_face( @edges ) Sketchup.active_model().selection().add( @group ) return @group end # of draw()
With that, I've already shown you way too much code. Time for you to add a
c() function and a
Circle class. Good luck! (Hint: my class constructor does nothing except save the inputs into instance variables. The whole class is the constructor and the
col()command adds one parameter: the distance to
pushpull()after you've drawn your circle. Add your own function and class. (Hint: if your Column's
draw()method goes more than three lines, you are working too hard.)
|RS||Rotation and Scale Matrix|
|U|| Unused or application-specific use
(may always be zero)
|Xt ...|| Translation Vector
(Wt may always be one)
Here's a ComponentInstance and its xform matrix in the Ruby Console:
The first thing I learned when I began looking at the xform matrix was that the Ruby Console didn't give you a good picture. I wanted a nice picture, so I frogged up a little WebDialog. That is the topic of Chapter 19, so I just give you the code here and invite you to copy it, not type it, into
your_sketch_talk.rb. First, the function
xf() goes into your SketchTalk command functions.
sprintf()Going right back to C, reappearing here in Ruby, the
printf()function outputs to the Ruby Console and the
sprintf()function outputs a string. Both can take arguments that direct the formatting of numbers. If we leave the formatting to the Ruby default, we'll get fractions with 15 decimal places. This is out of hand.
Here we'll use this format specifier:
'%6.3f' to specify floating point, 6 places total, 3 places after the decimal point. (Ask Google for additional
xform()function, in your support functions section:
def xform( html ) model = Sketchup.active_model() sel = model.selection() if sel.length() == 0 puts 'Nothing selected.' return end thing = sel if thing.is_a?( Sketchup::ComponentInstance ) || thing.is_a?( Sketchup::Group ) trans = thing.transformation() else puts 'model.selection() is not a Group or ComponentInstance.' return end # we don't really want stuff like 0.707106781186548 nums = trans.to_a() snums =  for i in 0..2 do snums.push( sprintf('%6.3f', nums[i]) ) end snums.push( nums.to_s() ) for i in 4..6 do snums.push( sprintf('%6.3f', nums[i]) ) end snums.push( nums.to_s() ) for i in 8..10 do snums.push( sprintf('%6.3f', nums[i]) ) end snums.push( nums.to_s() ) for i in 12..15 do snums.push( nums[i].to_s() ) end html += snums.inspect() html += " set_vals( vals );