1:import java.applet.*;
2:import java.awt.*;
3:import java.awt.event.*;
4:import java.awt.geom.*;
5:
6:public class CurveFit 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: // Midpoint between p1 and p2
68: double pDX = 0.0;
69: double pDY = 0.0;
70: // Midpoint between p0 and p1
71: double pEX = 0.0;
72: double pEY = 0.0;
73: double mAB = 0.0; // Slope of p1 to p2
74: double mBC = 0.0; // Slope of p2 to p3
75: double mDF = 0.0; // Slope from mid of p1-p2 to center of circle (center line 2)
76: double mEF = 0.0; // Slope from mid of p2-p3 to center of circle (center line 1)
77: boolean iDF = false; // Slope is vertical/infinity
78: boolean iEF = false; // Slope is vertical/infinity
79: double bDF = 0.0; // X-intercept of center line 2
80: double bEF = 0.0; // X-intercept of center line 1
81: // Center point of the curve
82: double pFX = 0.0;
83: double pFY = 0.0;
84:
85: g.setColor( Color.green );
86:
87: // Fill circles at the 3 points used
88: fillOval(g,x[1],y[1],7);
89: fillOval(g,x[2],y[2],7);
90: fillOval(g,x[3],y[3],7);
91:
92: // Draw lines between those three points
93: g.drawLine((int)x[1],(int)y[1],(int)x[2],(int)y[2]);
94: g.drawLine((int)x[2],(int)y[2],(int)x[3],(int)y[3]);
95:
96: g.setColor( Color.red );
97:
98: // Calculate the midpoints between the main points
99: pDX = x[1] + ((x[2]-x[1])/2.0);
100: pDY = y[1] + ((y[2]-y[1])/2.0);
101: pEX = x[2] + ((x[3]-x[2])/2.0);
102: pEY = y[2] + ((y[3]-y[2])/2.0);
103:
104: // Fill circles at the midpoints of those two lines
105: fillOval(g,pDX,pDY,7);
106: fillOval(g,pEX,pEY,7);
107:
108: // Get the slope perpendicular to the line between p1 and p2
109: if( (x[2]-x[1]) == 0 )
110: {
111: mDF = 0;
112: }
113: else if( (y[2]-y[1]) != 0 )
114: {
115: mAB = ((y[2]-y[1])/(x[2]-x[1]));
116: mDF = -1/mAB;
117: }
118: else
119: {
120: iDF = true;
121: }
122:
123: // Get the slope perpendicular to the line between p2 and p3
124: if( (x[3]-x[2]) == 0 )
125: {
126: mEF = 0;
127: }
128: else if( (y[3]-y[2]) != 0 )
129: {
130: mBC = ((y[3]-y[2])/(x[3]-x[2]));
131: mEF = -1/mBC;
132: }
133: else
134: {
135: iEF = true;
136: }
137:
138: // Calculate the x-intercepts of the lines to the center
139: bDF = -1 * (mDF*pDX - pDY);
140: bEF = -1 * (mEF*pEX - pEY);
141:
142: // If the lines are perpendicular, there will be no center point
143: if( (mDF == mEF) && (iDF == iEF))
144: return;
145:
146: // Calculate the center point of the circle
147: if(iDF == true)
148: {
149: pFX = pDX;
150: pFY = mEF*pFX + bEF;
151: }
152: else if(iEF == true)
153: {
154: pFX = pEX;
155: pFY = mDF*pFX + bDF;
156: }
157: else
158: {
159: pFX = (bEF - bDF)/(mDF - mEF);
160: pFY = mDF*pFX + bDF;
161: }
162:
163: // Draw lines to the center
164: g.setColor( Color.red );
165: g.drawLine((int)pDX,(int)pDY,(int)pFX,(int)pFY);
166: g.drawLine((int)pEX,(int)pEY,(int)pFX,(int)pFY);
167:
168: // Fill the center point
169: g.setColor( Color.blue );
170: fillOval(g,pFX,pFY,7);
171:
172: // Draw lines from p1, p2, p3 to the center
173: g.drawLine((int)x[1],(int)y[1],(int)pFX,(int)pFY);
174: g.drawLine((int)x[2],(int)y[2],(int)pFX,(int)pFY);
175: g.drawLine((int)x[3],(int)y[3],(int)pFX,(int)pFY);
176:
177: // Get the radius of the circle
178: double R = Math.sqrt(Math.pow(x[1]-pFX,2)+Math.pow(y[1]-pFY,2));
179:
180: // Draw the circle itself
181: g.drawOval((int)(pFX-R),(int)(pFY-R),(int)R*2,(int)R*2);
182: }
183:}