/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2006-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.geometry.iso.util.elem2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; /** * @author Jackson Roehrig & Sanjay Jena * * Circle2D A circle, representated by a X- and Y- Coordinate and a radius r. This * class provides a constructor building a unique circle from 3 points. * * This class was translated from CPP into Java The original source code can be * found at http://astronomy.swin.edu.au/~pbourke/geometry/circlefrom3/ * * * * @source $URL$ */ public class Circle2D { private double x = 0; private double y = 0; private double radius = 0; public Circle2D(double centerX, double centerY, double radius) { this.x = centerX; this.y = centerY; this.radius = radius; } /** * Constructs a circle from three points * @param First node * @param Second node * @param Thirs node */ public Circle2D(Point2D pt1, Point2D pt2, Point2D pt3) { this.radius=-1; // error checking if (!this.isPerpendicular(pt1, pt2, pt3) ) this.CalcCircle(pt1, pt2, pt3); else if (!this.isPerpendicular(pt1, pt3, pt2) ) this.CalcCircle(pt1, pt3, pt2); else if (!this.isPerpendicular(pt2, pt1, pt3) ) this.CalcCircle(pt2, pt1, pt3); else if (!this.isPerpendicular(pt2, pt3, pt1) ) this.CalcCircle(pt2, pt3, pt1); else if (!this.isPerpendicular(pt3, pt2, pt1) ) this.CalcCircle(pt3, pt2, pt1); else if (!this.isPerpendicular(pt3, pt1, pt2) ) this.CalcCircle(pt3, pt1, pt2); else { throw new IllegalArgumentException("The three pts are perpendicular to axis\n"); } } // Check the given node are perpendicular to x or y axis private boolean isPerpendicular(Point2D pt1, Point2D pt2, Point2D pt3) { double yDelta_a= pt2.getY() - pt1.getY(); double xDelta_a= pt2.getX() - pt1.getX(); double yDelta_b= pt3.getY() - pt2.getY(); double xDelta_b= pt3.getX() - pt2.getX(); // checking whether the line of the two pts are vertical if (Math.abs(xDelta_a) <= 0.000000001 && Math.abs(yDelta_b) <= 0.000000001){ return false; } return ((Math.abs(yDelta_a) <= 0.0000001) || (Math.abs(yDelta_b) <= 0.0000001) || (Math.abs(xDelta_a) <= 0.000000001) || (Math.abs(xDelta_b) <= 0.000000001)); } private double CalcCircle(Point2D pt1, Point2D pt2, Point2D pt3) { double yDelta_a= pt2.getY() - pt1.getY(); double xDelta_a= pt2.getX() - pt1.getX(); double yDelta_b= pt3.getY() - pt2.getY(); double xDelta_b= pt3.getX() - pt2.getX(); if (Math.abs(xDelta_a) <= 0.000000001 && Math.abs(yDelta_b) <= 0.000000001){ this.x= 0.5*(pt2.getX() + pt3.getX()); this.y= 0.5*(pt1.getY() + pt2.getY()); this.radius= pt1.distance(this.getCenter()); return this.radius; } // IsPerpendicular() assure that xDelta(s) are not zero double aSlope=yDelta_a/xDelta_a; double bSlope=yDelta_b/xDelta_b; if (Math.abs(aSlope-bSlope) <= 0.000000001) { // checking whether the given points are colinear. throw new IllegalArgumentException("The three pts are colinear\n"); } // calc center this.x= (aSlope*bSlope*(pt1.getY() - pt3.getY()) + bSlope*(pt1.getX() + pt2.getX()) - aSlope*(pt2.getX() + pt3.getX()) )/(2* (bSlope-aSlope) ); this.y = -1*(this.x - (pt1.getX() + pt2.getX())/2)/aSlope + (pt1.getY() + pt2.getY())/2; this.radius= pt1.distance(this.getCenter()); return this.radius; } /** * * @return */ public double getX() { return this.x; } /** * * @return */ public double getY() { return this.y; } /** * * @return */ public double getRadius() { return this.radius; } /** * * @return */ public Point2D getCenter() { return new Point2D.Double(this.x, this.y); } /** * @param radius The radius to set. */ public void setRadius(double radius) { this.radius = radius; } /** * @param x The x to set. */ public void setX(double x) { this.x = x; } /** * @param y The y to set. */ public void setY(double y) { this.y = y; } public void setValues(double x, double y, double radius) { this.x = x; this.y = y; this.radius = radius; } /** * Verifies weather the circle contains a node or not. * Point laying at the border of the circle are not contained by the circle. * @param dp * @return */ public boolean contains(Point2D dp) { double dx = this.x - dp.getX(); double dy = this.y - dp.getY(); return ((dx*dx) + (dy*dy)) < (this.radius*this.radius); } public Rectangle2D getRectangle() { return new Rectangle2D.Double(x-radius,y-radius,2*radius,2*radius); } public String toString() { return "Circle2D: X:"+this.x+" Y:"+this.y+" r:"+this.radius; } }