/*
The Design Patterns Java Companion
Copyright (C) 1998, by James W. Cooper
IBM Thomas J. Watson Research Center
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TriangleDrawing extends JFrame {
stdTriangle t, t1;
IsocelesTriangle it;
public TriangleDrawing() {
super("Draw triangles");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
TPanel tp = new TPanel();
t = new stdTriangle(new Point(10, 10), new Point(150, 50), new Point(
100, 75));
it = new IsocelesTriangle(new Point(150, 100), new Point(240, 40),
new Point(175, 150));
t1 = new stdTriangle(new Point(150, 100), new Point(240, 40),
new Point(175, 150));
tp.addTriangle(t);
tp.addTriangle(it);
// tp.addTriangle(t1);
getContentPane().add(tp);
setSize(300, 200);
setBackground(Color.white);
setVisible(true);
}
public static void main(String[] arg) {
new TriangleDrawing();
}
}
class TPanel extends JPanel {
Vector triangles;
public TPanel() {
triangles = new Vector();
}
public void addTriangle(Triangle t) {
triangles.addElement(t);
}
public void paint(Graphics g) {
for (int i = 0; i < triangles.size(); i++) {
Triangle tngl = (Triangle) triangles.elementAt(i);
tngl.draw(g);
}
}
}
abstract class Triangle {
Point p1, p2, p3;
public Triangle(Point a, Point b, Point c) {
//save
p1 = a;
p2 = b;
p3 = c;
}
public void draw(Graphics g) {
//This routine draws a general triangle
drawLine(g, p1, p2);
Point current = draw2ndLine(g, p2, p3);
closeTriangle(g, current);
}
public void drawLine(Graphics g, Point a, Point b) {
g.drawLine(a.x, a.y, b.x, b.y);
}
//this routine is the "Hook" that has to be implemented
//for each triangle type.
abstract public Point draw2ndLine(Graphics g, Point a, Point b);
public void closeTriangle(Graphics g, Point c) {
//draw back to first point
g.drawLine(c.x, c.y, p1.x, p1.y);
}
}
class stdTriangle extends Triangle {
public stdTriangle(Point a, Point b, Point c) {
super(a, b, c);
}
public Point draw2ndLine(Graphics g, Point a, Point b) {
g.drawLine(a.x, a.y, b.x, b.y);
return b;
}
}
class IsocelesTriangle extends Triangle {
Point newc;
int newcx, newcy;
int incr;
public IsocelesTriangle(Point a, Point b, Point c) {
super(a, b, c);
double dx1 = b.x - a.x;
double dy1 = b.y - a.y;
double dx2 = c.x - b.x;
double dy2 = c.y - b.y;
double side1 = calcSide(dx1, dy1);
double side2 = calcSide(dx2, dy2);
if (side2 < side1)
incr = -1;
else
incr = 1;
double slope = dy2 / dx2;
double intercept = c.y - slope * c.x;
//move point c so that this is an isoceles triangle
newcx = c.x;
newcy = c.y;
while (Math.abs(side1 - side2) > 1) {
newcx += incr; //iterate a pixel at a time until close
newcy = (int) (slope * newcx + intercept);
dx2 = newcx - b.x;
dy2 = newcy - b.y;
side2 = calcSide(dx2, dy2);
}
newc = new Point(newcx, newcy);
}
//calculate length of side
private double calcSide(double dx, double dy) {
return Math.sqrt(dx * dx + dy * dy);
}
//draws 2nd line using saved new point
public Point draw2ndLine(Graphics g, Point b, Point c) {
g.drawLine(b.x, b.y, newc.x, newc.y);
return newc;
}
}