Graphics2D Shear Applet
In this example we shear a rectangle with dimensions half the width by half the height of the applet. Its top left vertex is positioned one quarter of the way across the applet and a quarter of the way down, so that it is centred in the applet.
Generally, the result of a shear parallel to the x-axis is, for each coordinate, x := x + c * y, where c is the constant supplied to create the required shape. For our motion graphic, we want the shape to change every 40 milliseconds, and to create the "constant" c we multiply a constant 0.02 by an integer i that takes values between 0 and 19. This results in a translation of the top of the shape of c * y = i * 0.02 * height / 4. It was necessary to provide a translation to compensate for the movement of the top line. (No such compensation is required if the rectangle to be sheared is at the top of the applet).
namespace shear_demo; // Thread code based on an applet by Michael McGuffin which was // converted to Oxygene for Java by Dharmesh Tailor interface uses java.util, java.applet.*, java.awt.*; type ShearApplet = public class(Applet, Runnable) private var width, height, i : Integer; var j : Integer := 0; var t : Thread := nil; var rect : Rectangle2D; var aT, at_shear : AffineTransform; var threadSuspended : Boolean; public method init; override; method start; override; method stop; override; method run; method paint(g : Graphics); override; end; implementation method ShearApplet.init; begin width := getSize.width; height := getSize.height; rect := new Rectangle2D.Float(width / 4, height / 4, width / 2, height / 2); setBackground(Color.red); end; //Executed after the applet is created //also whenever the browser returns to the page containing the applet method ShearApplet.start; begin if t = nil then begin t := new Thread(self); threadSuspended := false; t.start; end else begin if threadSuspended then begin threadSuspended := false; locking self do begin notify; end; end; end; end; //Executed whenever the browser leaves the page containing the applet method ShearApplet.stop; begin threadSuspended := true; end; //Executed within the thread that this applet created method ShearApplet.run; begin try while j < 59 do begin //Where the thread does some work inc(j); i := j MOD 20; //Thread checks to see if it should suspend itself if threadSuspended then begin locking self do begin while threadSuspended do begin wait; end; end; end; repaint; t.sleep(40); //Interval given in milliseconds end; except on e : InterruptedException do begin end; end; end; method ShearApplet.paint(g : Graphics); var g2 : Graphics2D; shearedRect : Shape; begin g2 := Graphics2D(g); aT := g2.getTransform; //save existing transform at_shear := new AffineTransform; at_shear.shear(i * 0.02, 0); at_shear.translate(-i * 0.02 * height / 4, 0); shearedRect := at_shear.createTransformedShape(rect); g2.setColor(Color.green); g2.fill(shearedRect); g2.setTransform(aT); //restore original transform end; end.