import java.awt.*; public class Line { Point A, B; // this is the line between A and B boolean isStraight; // if it's a circle, then a center C and radius r are needed Point C; double r; // if it's is a straight line, then a point P and a direction D // are needed Point P; Point D; public Line (Point A, Point B) { this.A = A; this.B = B; // first determine if its a line or a circle double den = A.x*B.y - B.x*A.y; isStraight = (Math.abs(den) < 1.0e-14); if (isStraight) { P = A; // a point on the line} // find a unit vector D in the direction of the line} den = Math.sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y)) ; D = new Point ((B.x - A.x) / den, (B.y - A.y) / den); } else { // it's a circle // find the center of the circle thru these points} double s1 = (1.0 + A.x*A.x + A.y*A.y) / 2.0; double s2 = (1.0 + B.x*B.x + B.y*B.y) / 2.0; C = new Point ((s1*B.y - s2*A.y) / den, (A.x*s2 - B.x*s1) / den); r = Math.sqrt(C.x*C.x+C.y*C.y - 1.0) ; } // if/else } // Line public String toString() { return "["+A+","+B+"]"; } // Reflect the point R thru the this line to get Q the returned point} public Point reflect (Point R) { Point Q = new Point(); if (isStraight) { double factor = 2.0 * ((R.x-P.x)*D.x + (R.y-P.y)*D.y) ; Q.x = 2.0 * P.x + factor * D.x - R.x ; Q.y = 2.0 * P.y + factor * D.y - R.y ; } else { // it's a circle double factor = r*r / ((R.x-C.x)*(R.x-C.x) + (R.y-C.y)*(R.y-C.y)) ; Q.x = C.x + factor * (R.x - C.x) ; Q.y = C.y + factor * (R.y - C.y) ; } // if/else return Q; } // reflect // append screen coordinates to the list in order to draw the line public SCL appendScreenCoordinates (SCL list, Dimension d) { int x_center = d.width/2; int y_center = d.height/2; int radius = Math.min(x_center,y_center); int x = (int)Math.round(A.x*radius+x_center); int y = (int)Math.round(A.y*radius+y_center); if ((list == null || x != list.x || y != list.y) && x!=Double.NaN && y!=Double.NaN) list = new SCL (list,x,y); if (isStraight) { // go directly to terminal point B x = (int)Math.round(B.x*radius+x_center); y = (int)Math.round(B.y*radius+y_center); if (x != list.x || y != list.y) list = new SCL (list,x,y); } else { // its an arc of a circle // determine starting and ending angles double alpha = Math.atan2((A.y-C.y),(A.x-C.x)); double beta = Math.atan2((B.y-C.y),(B.x-C.x)); if (Math.abs(beta-alpha) > Math.PI) if (beta < alpha) beta += 2.0*Math.PI; else alpha += 2.0*Math.PI; CircularCurve curve = new CircularCurve(C.x,C.y,r); curve.setScreen(x_center,y_center,radius); list = curve.interpolate(list,alpha,beta); } return list; } // appendScreenCoordinates public void draw(Graphics g, Dimension d) { int x_center = d.width/2; int y_center = d.height/2; int radius = Math.min(x_center,y_center); // *** yet to write *** } // draw } // Line