// // $Id: TransformCanvas.java,v 1.1 1999/01/13 22:46:07 min Exp min $ // package transform; import java.awt.*; import vectors.*; public class TransformCanvas extends Canvas { private static final double NR_STEPS = 10; private static final int STEP_PAUSE = 250; // pause for 250 msec after each transform private Image offscreen; private int image_width; private int image_height; private GraphicsObject house = new GraphicsObject(); private GraphicsObject face = new GraphicsObject(); private GraphicsObject current_object = face; private Matrix initial_matrix = new Matrix(); private Matrix transform_matrix = new Matrix(); private Matrix viewport_transform = new Matrix(); private Matrix prev_matrix = new Matrix(); private boolean display_original = false; private boolean display_previous = false; public TransformCanvas() { define_house(); define_face(); reset_transform(); initial_matrix.identity(); // translate(75, 0, 0); prev_matrix.identity(); } // constructor public void set_face() { current_object = face; } public void set_house() { current_object = house; } private void define_house() { Polygon p = new Polygon(); p.addPoint(-40, 40); p.addPoint(-40, -30); p.addPoint( 40, -30); p.addPoint( 40, 40); house.set_colour(Color.black); house.add_polygon(p); p = new Polygon(); p.addPoint(-40, -30); p.addPoint( 40, -30); p.addPoint( 0, -80); house.add_polygon(p); p = new Polygon(); p.addPoint( 10, 40); p.addPoint( 25, 40); p.addPoint( 25, 5); p.addPoint( 10, 5); house.set_colour(new Color((float) 0.42, (float) 0.11, (float) 0.11)); house.add_polygon(p); p = new Polygon(); p.addPoint(-20, 20); p.addPoint(-10, 20); p.addPoint(-10, 10); p.addPoint(-20, 10); house.set_colour(Color.blue); house.add_polygon(p); p = new Polygon(); p.addPoint(10, -10); p.addPoint(20, -10); p.addPoint(20, -20); p.addPoint(10, -20); house.add_polygon(p); p = new Polygon(); p.addPoint(-20, -10); p.addPoint(-10, -10); p.addPoint(-10, -20); p.addPoint(-20, -20); house.add_polygon(p); p = new Polygon(); p.addPoint(-5, -50); p.addPoint( 5, -50); p.addPoint( 5, -60); p.addPoint(-5, -60); house.add_polygon(p); } // define_house public void add_circle(GraphicsObject obj, int x, int y, int radius) { Polygon p = new Polygon(); for(double i=0.0; i <= 2 * Math.PI; i += 0.25) { double cx = (double) x + radius * Math.cos(i); double cy = (double) y + radius * Math.sin(i); p.addPoint((int) cx, (int) cy); } obj.add_polygon(p); } // add_circle public void define_face() { face.set_colour(Color.blue); add_circle(face, 0, 0, 100); add_circle(face, -50, -20, 30); add_circle(face, 50, -20, 30); Polygon p = new Polygon(); p.addPoint(-40, 50); p.addPoint(40, 50); p.addPoint(0, 70); face.add_polygon(p); } // define_face public void toggle_display_original() { display_original = !display_original; } public void toggle_display_previous() { display_previous = !display_previous; } public void store_current_matrix() { prev_matrix.set(transform_matrix.matrix_multiply(initial_matrix)); } public void paint() { Dimension d = this.size(); if ((offscreen == null) || (d.width != image_width) || (d.height != image_height)) { if ((d.width < 1) || (d.height < 1)) return; offscreen = this.createImage(d.width, d.height); image_width = d.width; image_height = d.height; int x = d.width/2; int y = d.height/2; viewport_transform.translate((double) x, (double) y, 0); } // if, window size has changed Graphics off_g = offscreen.getGraphics(); clear(off_g); draw_axes(off_g); if (display_original) { current_object.set_state(GraphicsObject.DISPLAY_GREY); current_object.set_grey_colour(Color.darkGray); current_object.draw(off_g, viewport_transform.matrix_multiply(initial_matrix)); current_object.set_state(GraphicsObject.DISPLAY_COLOUR); } if (display_previous) { current_object.set_state(GraphicsObject.DISPLAY_GREY); current_object.set_grey_colour(Color.red); current_object.draw(off_g, viewport_transform.matrix_multiply(prev_matrix)); current_object.set_state(GraphicsObject.DISPLAY_COLOUR); } Matrix total_transform = new Matrix(); total_transform = transform_matrix.matrix_multiply(initial_matrix); current_object.draw(off_g, viewport_transform.matrix_multiply(total_transform)); Graphics my_g = this.getGraphics(); my_g.drawImage(offscreen, 0, 0, this); } // paint public void paint(Graphics g) { paint(); } void clear(Graphics g) { g.setColor(new Color((float) 0.93, (float) 0.91, (float) 0.67)); g.fillRect(0, 0, image_width, image_height); } // clear void draw_axes(Graphics g) { Dimension d = this.size(); int x = d.width/2; int y = d.height/2; g.setColor(Color.black); g.drawLine(0, y, d.width, y); g.drawLine(x, 0, x, d.height); g.drawString("x", d.width - 15, y - 10); g.drawString("y", x - 15, 15); // // draw markers and numbers on y-axis // g.setFont(new Font("Helvetica", Font.BOLD, 8)); int count = 0; for(int i=0; i < x; i += 25) { g.drawLine(x + i, y, x + i, y + 5); g.drawLine(x - i, y, x - i, y + 5); if ((count % 4) == 0) { if (i > 0) { g.drawString(Integer.toString(i), x + i - 10, y + 15); g.drawString(Integer.toString(-i), x - i - 15, y + 15); } } count++; } // // draw markers and numbers on x-axis // for(int i=0; i < y; i += 25) { g.drawLine(x, y + i, x + 5, y + i); g.drawLine(x, y - i, x + 5, y - i); if ((count % 4) == 0) { g.drawString(Integer.toString(i), x + 2, y - i - 2); if (i > 0) g.drawString(Integer.toString(-i), x + 2, y + i - 2); } count++; } } // draw_axes public void smooth_scale(double scale) { Matrix orig_matrix = new Matrix(transform_matrix); Matrix temp = new Matrix(); double delta = (scale - 1.0) / TransformCanvas.NR_STEPS; for(double i=1.0; ((i<=scale) && (scale > 1.0)) || ((i>=scale) && (scale < 1.0)); i += delta) { temp.scale(i, i, 0); transform_matrix = temp.matrix_multiply(orig_matrix); paint(); } // for temp.scale(scale, scale, 0); transform_matrix = temp.matrix_multiply(orig_matrix); paint(); try { Thread.sleep(STEP_PAUSE); } catch (InterruptedException e) {} } // smooth_scale public void smooth_rotate(double angle) { Matrix orig_matrix = new Matrix(transform_matrix); Matrix temp = new Matrix(); double delta = angle / TransformCanvas.NR_STEPS; for(double i=0.0; ((i <= angle) && (angle > 0)) || ((i >= angle) && (angle < 0)); i += delta) { temp.rotate_z(i); transform_matrix = temp.matrix_multiply(orig_matrix); paint(); } // for temp.rotate_z(angle); transform_matrix = temp.matrix_multiply(orig_matrix); paint(); try { Thread.sleep(STEP_PAUSE); } catch (InterruptedException e) {} } // smooth_rotate public void smooth_translate(double dx, double dy) { Matrix orig_matrix = new Matrix(transform_matrix); dy = -dy; double delta_x = dx / TransformCanvas.NR_STEPS; double delta_y = dy / TransformCanvas.NR_STEPS; double cx = 0; double cy = 0; for(int i=0; i < TransformCanvas.NR_STEPS; i++, cx += delta_x, cy += delta_y) { Matrix temp = new Matrix(); temp.translate(cx, cy, 0.0); transform_matrix = temp.matrix_multiply(orig_matrix); paint(); } // for paint(); try { Thread.sleep(STEP_PAUSE); } catch (InterruptedException e) {} } // smooth_translate public void reset_transform() { transform_matrix.identity(); paint(); } // reset_transform } // class TransformCanvas