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.

Programming - a skill for life!

Applets using Graphics2D for transforms, gradient painting and pixel drawing in Oxygene for Java