This is by far the most fun I've had testing code since playing RoboCode. Click & drag to stretch things, right-click & drag to move the points. Works beautifully!! -- Simonton package rednaxela; import java.awt.*; import java.awt.event.*; import javax.swing.*; /** * @author Eric Simonton */ public class Tester extends JPanel { public static void main(String[] args) { JFrame frame = new JFrame("Stretch"); frame.setContentPane(new Tester()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocationByPlatform(true); frame.pack(); frame.setVisible(true); } private Point[] corners = new Point[8]; private Point[] r1 = new Point[4]; private Point[] r2 = new Point[4]; private Point[] points = new Point[2]; public Tester() { setPreferredSize(new Dimension(800, 400)); r1[0] = corners[0] = new Point(20, 20); r1[1] = corners[1] = new Point(20, 380); r1[2] = corners[2] = new Point(380, 380); r1[3] = corners[3] = new Point(380, 20); points[0] = new Point(200, 200); r2[0] = corners[4] = new Point(420, 20); r2[1] = corners[5] = new Point(420, 380); r2[2] = corners[6] = new Point(780, 380); r2[3] = corners[7] = new Point(780, 20); points[1] = new Point(600, 200); Mouser mouser = new Mouser(); addMouseListener(mouser); addMouseMotionListener(mouser); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); Graphics2D g2d = (Graphics2D) g; Polygon rect = new Polygon(); for (int i = 8; --i >= 0; ) { rect.addPoint(corners[i].x, corners[i].y); if (i % 4 == 0) { g2d.draw(rect); rect.reset(); } } g.setColor(Color.RED); g.fillOval(points[0].x - 1, points[0].y - 1, 4, 4); g.fillOval(points[1].x - 1, points[1].y - 1, 4, 4); } private int getClosestCorner(Point p) { return getClosestPoint(p, corners); } private int getClosestPoint(Point p) { return getClosestPoint(p, points); } private int getClosestPoint(Point p, Point[] points) { int closestPoint = 0; double closestDistance = points[0].distance(p); for (int i = points.length; --i > 0;) { double dist = points[i].distance(p); if (dist < closestDistance) { closestDistance = dist; closestPoint = i; } } return closestPoint; } private void setCorner(int i, Point p) { corners[i].setLocation(p); recalculate(i > 3); } private void setPoint(int i, Point p) { points[i].setLocation(p); recalculate(i < 1); } private void recalculate(boolean firstIsConstant) { if (firstIsConstant) { points[1].setLocation(Utils.solveElasticProblem(r1, r2, points[0])); } else { points[0].setLocation(Utils.solveElasticProblem(r2, r1, points[1])); } repaint(); } private class Mouser extends MouseAdapter implements MouseMotionListener { private boolean corner; private int clickPoint; public void mousePressed(MouseEvent e) { if (e.getButton() == 1) { corner = true; clickPoint = getClosestCorner(e.getPoint()); } else { corner = false; clickPoint = getClosestPoint(e.getPoint()); } mouseDragged(e); } public void mouseDragged(MouseEvent e) { if (corner) { setCorner(clickPoint, e.getPoint()); } else { setPoint(clickPoint, e.getPoint()); } } public void mouseMoved(MouseEvent e) { // don't care } } }
|