[Newbies] Drawing with Morphic Transforms

Bert Freudenberg bert at freudenbergs.de
Tue Oct 18 09:22:25 UTC 2011

On 18.10.2011, at 06:09, Jeff G wrote:

> Hi Everyone,
> My question concerns how to correctly use transforms when drawing in Morphic.  I have created a morph and overridden its drawOn: method so that I can convert the canvas passed in to a BalloonCanvas so I can get anti-aliasing when I draw, and subsequently to a clipping canvas so that I can draw figures outside the bounds of the morph without actually drawing past the morph and onto the Display.  
> One of the things that I would like to do is allow for shapes I am drawing to be given an arbitrary scale, translation, and rotation.  Each shape would have an associated transform so that when they are asked to draw they would set their transform on the canvas and draw as though they are situated at the origin and the transform will take care of having the actual rendering occur in the correct location.  Ie if a rectangle has size of 20 at 20 and the morph has its bounds starting from 500 at 400 (topLeft) then ultimately the rectangle will start drawing from 500 at 400 to 520 at 420, and thus will display correctly in the morph.
> My problem is that I cannot seem to get the canvas to actually take into account the transform that I am setting during drawing.  I can call transformBy: or transformBy:clipTo:during: passing in either a MatrixTransform2x3 or a MorphicTransform, with both being given an offset of the Morph's topLeft.  I then draw a rectangle at 0 at 0 with a extent of 100 at 100.  My experience with other vector drawing toolkits would lead me to believe that this should cause the rectangle to draw in the top left corner of the morph no matter where it is onscreen, but alas the rectangle only appears when I move the morph to the top left of the display, meaning that the transform isn't causing an offset to take place during the drawing.
> Any pointers that could be offered to allow me to get my drawing up and fully transformed would be greatly appreciated as I would like to work on a simple asteroids game after this, and I will be using transforms of basic shapes extensively as they travel around the screen.

It does work, but read below for things that may trip you up:

	c := Display getCanvas asBalloonCanvas.
	c aaLevel: 4.
	c transformBy: (MatrixTransform2x3 withOffset: 100 at 100).
	c transformBy: (MatrixTransform2x3 withAngle: 20).
	c drawRectangle: (0 at 0 extent: 100 at 50) color: Color red borderWidth: 1 borderColor: Color black.

Note that the transform is taken into account only for Balloon drawing. BalloonCanvas inherits from FormCanvas. It overrides most FormCanvas drawing methods, but you may find some that are not overridden.

For most efficiency, use the drawBezier* methods. Balloon can be quite efficient. It was developed to play back Flash animations, though the Flash file support has been removed in recent Squeak releases. 

Morphic generally uses FormCanvas, which does not allow arbitrary transforms. For rotation and scaling it falls back to warping bitmaps. That's because it's older than Balloon, and never was converted to use properly nested transformed drawing.

Another source of confusion might be that (in contrast to most other scene-graph APIs) Morphic uses absolute coordinates. When you move a Morph, it actually adjusts all the bounds of its submorphs. You will have to override that mechanism in your own Shape hierarchy.  Again, look at the Flash player if you need an example how to do this.

- Bert -

More information about the Beginners mailing list