/** * Computes the center of the circumscribed circle of the three input points. * * @throws ColinearPoints2DException if the 3 points are colinear */ public static Point2D circumCenter(Point2D p1, Point2D p2, Point2D p3) { if (Point2D.isColinear(p1, p2, p3)) throw new ColinearPoints2DException(p1, p2, p3); // create two median lines StraightLine2D line12 = StraightLine2D.createMedian(p1, p2); StraightLine2D line23 = StraightLine2D.createMedian(p2, p3); // check medians are not parallel assert !AbstractLine2D.isParallel(line12, line23) : "If points are not colinear, medians should not be parallel"; // Compute intersection of the medians, and circle radius Point2D center = AbstractLine2D.getIntersection(line12, line23); // return the center return center; }
/** * Computes intersections of a circle with a line. Returns an array of Point2D, of size 0, 1 or 2 * depending on the distance between circle and line. If there are 2 intersections points, the * first one in the array is the first one on the line. * * @return a collection of intersection points * @since 0.11.1 */ public static Collection<Point2D> lineCircleIntersections( LinearShape2D line, CircularShape2D circle) { // initialize array of points (maximum 2 intersections) ArrayList<Point2D> intersections = new ArrayList<Point2D>(2); // extract parameters of the circle Circle2D parent = circle.supportingCircle(); Point2D center = parent.center(); double radius = parent.radius(); // Compute line perpendicular to the test line, and going through the // circle center StraightLine2D perp = StraightLine2D.createPerpendicular(line, center); // Compute distance between line and circle center Point2D inter = perp.intersection(new StraightLine2D(line)); if (inter == null) { throw new RuntimeException( "Could not compute intersection point when computing line-cicle intersection"); } double dist = inter.distance(center); // if the distance is the radius of the circle, return the // intersection point if (abs(dist - radius) < Shape2D.ACCURACY) { if (line.contains(inter) && circle.contains(inter)) intersections.add(inter); return intersections; } // compute angle of the line, and distance between 'inter' point and // each intersection point double angle = line.horizontalAngle(); double d2 = sqrt(radius * radius - dist * dist); // Compute position and angle of intersection points Point2D p1 = Point2D.createPolar(inter, d2, angle + Math.PI); Point2D p2 = Point2D.createPolar(inter, d2, angle); // add points to the array only if they belong to the line if (line.contains(p1) && circle.contains(p1)) intersections.add(p1); if (line.contains(p2) && circle.contains(p2)) intersections.add(p2); // return the result return intersections; }
/* (non-Javadoc) * @see math.geom2d.circulinear.CirculinearCurve2D#transform(math.geom2d.transform.CircleInversion2D) */ public CircleLine2D transform(CircleInversion2D inv) { // Extract inversion parameters Point2D center = inv.center(); Point2D c1 = this.center(); // If circles are concentric, creates directly the new circle if (center.distance(c1) < Shape2D.ACCURACY) { double r0 = inv.radius(); double r2 = r0 * r0 / this.r; return new Circle2D(center, r2, this.direct); } // line joining centers of the two circles StraightLine2D centersLine = new StraightLine2D(center, c1); // get the two intersection points with the line joining the circle centers Collection<Point2D> points = this.intersections(centersLine); if (points.size() < 2) { throw new RuntimeException( "Intersection of circle with line through center has less than 2 points"); } Iterator<Point2D> iter = points.iterator(); Point2D p1 = iter.next(); Point2D p2 = iter.next(); // If the circle contains the inversion center, it transforms into a // straight line if (this.distance(center) < Shape2D.ACCURACY) { // choose the intersection point that is not the center double dist1 = center.distance(p1); double dist2 = center.distance(p2); Point2D p0 = dist1 < dist2 ? p2 : p1; // transform the point, and return the perpendicular p0 = p0.transform(inv); return StraightLine2D.createPerpendicular(centersLine, p0); } // For regular cases, the circle transforms into an other circle // transform the two extreme points of the circle, // resulting in a diameter of the new circle p1 = p1.transform(inv); p2 = p2.transform(inv); // compute center and diameter of transformed circle double diam = p1.distance(p2); c1 = Point2D.midPoint(p1, p2); // create the transformed circle boolean direct = !this.isDirect() ^ this.isInside(inv.center()); return new Circle2D(c1, diam / 2, direct); }