1:import java.applet.*;
2:import java.awt.*;
3:import java.awt.event.*;
4:import java.awt.geom.*;
5:
6:public class CurveFitII extends Applet implements MouseListener, MouseMotionListener {
7:
8: double x[];
9: double y[];
10: int selected;
11:
12: public void init() {
13: selected = 0;
14: x = new double[4];
15: y = new double[4];
16: x[1] = 40;
17: y[1] = 150;
18: x[2] = 75;
19: y[2] = 75;
20: x[3] = 150;
21: y[3] = 40;
22:
23: setBackground( Color.black );
24: addMouseListener(this);
25: addMouseMotionListener(this);
26: }
27:
28: public void mousePressed(MouseEvent e) {
29: int mx = e.getX();
30: int my = e.getY();
31: Ellipse2D check;
32: for(int i = 0; i < 4; i++)
33: {
34: check = new Ellipse2D.Double(x[i]-6,y[i]-6,11,11);
35: if(check.contains(mx,my))
36: selected = i;
37: }
38: }
39:
40: public void mouseReleased(MouseEvent e) {
41: selected = 0;
42: }
43:
44: public void mouseEntered(MouseEvent e) {
45: }
46:
47: public void mouseExited(MouseEvent e) {
48: }
49:
50: public void mouseClicked(MouseEvent e) {
51: }
52:
53: public void mouseMoved(MouseEvent e) {
54: }
55:
56: public void mouseDragged(MouseEvent e) {
57: x[selected] = e.getX();
58: y[selected] = e.getY();
59: repaint();
60: }
61:
62: public void fillOval(Graphics g, double xc, double yc, double size) {
63: g.fillOval((int)(xc-(size/2.0)),(int)(yc-(size/2.0)), (int)(size), (int)(size));
64: }
65:
66: public void paint( Graphics g )
67: {
68: Point2D p1 = new Point2D.Double(x[1],y[1]);
69: Point2D p2 = new Point2D.Double(x[2],y[2]);
70: Point2D p3 = new Point2D.Double(x[3],y[3]);
71: Ellipse2D c = makeCircle(p1,p2,p3);
72:
73: // Fill circles at the 3 points used
74: g.setColor( Color.green );
75: fillOval(g,x[1],y[1],7);
76: fillOval(g,x[2],y[2],7);
77: fillOval(g,x[3],y[3],7);
78:
79: // Draw lines between those three points
80: g.drawLine((int)x[1],(int)y[1],(int)x[2],(int)y[2]);
81: g.drawLine((int)x[2],(int)y[2],(int)x[3],(int)y[3]);
82:
83: if(c != null)
84: {
85: double cx = c.getX() + c.getWidth()/2.0;
86: double cy = c.getY() + c.getHeight()/2.0;
87:
88: g.setColor( Color.blue );
89:
90: // Fill the center point
91: fillOval(g,cx,cy,7);
92:
93: // Draw lines from p1, p2, p3 to the center
94: g.drawLine((int)x[1],(int)y[1],(int)cx,(int)cy);
95: g.drawLine((int)x[2],(int)y[2],(int)cx,(int)cy);
96: g.drawLine((int)x[3],(int)y[3],(int)cx,(int)cy);
97:
98: // Draw the circle
99: g.drawOval((int)c.getX(),(int)c.getY(),(int)c.getWidth(),(int)c.getHeight());
100: }
101: }
102:
103: // Get distance between two points
104: public static double getDistanceOfPoints(double p1x, double p1y, double p2x, double p2y)
105: {
106: double offsetX = p2x-p1x;
107: double offsetY = p2y-p1y;
108: return Math.sqrt(Math.pow(offsetX,2)+Math.pow(offsetY,2));
109: }
110:
111: // Get the cross product of two vectors
112: public static double getCrossProduct(Point2D p1, Point2D p2)
113: {
114: return (p1.getX() * p2.getY() - p1.getY() * p2.getX());
115: }
116:
117: // Make a circle from three points (Will return null if points are coplanar)
118: public Ellipse2D makeCircle(Point2D p1, Point2D p2, Point2D p3)
119: {
120: Ellipse2D circle = null;
121: // vector of edge opposite of p2
122: Point2D v2 = new Point2D.Double(p2.getX()-p1.getX(),p2.getY()-p1.getY());
123: // vector of edge opposite of p3
124: Point2D v3 = new Point2D.Double(p3.getX()-p1.getX(),p3.getY()-p1.getY());
125:
126: // Check the cross product to ensure the points are not coplanar
127: if (getCrossProduct(v2,v3) != 0.0)
128: {
129: double a = p1.getX();
130: double b = p1.getY();
131: double c = p2.getX();
132: double d = p2.getY();
133: double e = p3.getX();
134: double f = p3.getY();
135: double absq = (a*a+b*b);
136: double cdsq = (c*c+d*d);
137: double efsq = (e*e+f*f);
138: double cx = 0;
139: double cy = 0;
140: double cr = 0;
141:
142: // Calculate the X coordinate of the center point
143: cx = (absq*(f-d)+cdsq*(b-f)+efsq*(d-b))/(2.0*(a*(f-d)+c*(b-f)+e*(d-b)));
144:
145: // Calculate the Y coordinate of the center point
146: cy = (absq*(e-c)+cdsq*(a-e)+efsq*(c-a))/(2.0*(b*(e-c)+d*(a-e)+f*(c-a)));
147:
148: // Calculate the radius of the circle
149: cr = getDistanceOfPoints(cx,cy,a,b);
150:
151: // Initialize the circle
152: circle = new Ellipse2D.Double(cx-cr,cy-cr,2*cr,2*cr);
153: }
154:
155: return circle;
156: }
157:}
158: