All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aima.core.util.math.geom.shapes.Circle2D Maven / Gradle / Ivy

Go to download

AIMA-Java Core Algorithms from the book Artificial Intelligence a Modern Approach 3rd Ed.

The newest version!
package aima.core.util.math.geom.shapes;

import aima.core.util.Util;

/**
 * This class implements a circle in a two-dimensional Cartesian plot.
* The circle is represented by a {@link Point2D} center and a {@code double} radius. * * @author Arno von Borries * @author Jan Phillip Kretzschmar * @author Andreas Walscheid * */ public class Circle2D implements IGeometric2D { private final Point2D center; private final double radius; /** * @param center the center point of the circle. * @param radius the radius of the circle. */ public Circle2D(Point2D center, double radius) { this.center = center; this.radius = radius; } /** * @param cx the x coordinate of the center point of the circle. * @param cy the y coordinate of the center point of the circle. * @param radius the radius of the circle. */ public Circle2D(double cx, double cy, double radius) { this.center = new Point2D(cx, cy); this.radius = radius; } /** * @return the center point of the circle. */ public Point2D getCenter() { return center; } /** * @return the radius of the circle. */ public double getRadius() { return radius; } @Override public Point2D randomPoint() { final double x = Util.generateRandomDoubleBetween(-radius,radius); final double maxY = Math.sqrt(radius*radius-x*x); final double y = Util.generateRandomDoubleBetween(-maxY, maxY); return new Point2D(center.getX()+x,center.getY()+y); } @Override public boolean isInside(Point2D point) { return center.vec(point).length() < radius; } @Override public boolean isInsideBorder(Point2D point) { return center.vec(point).length() <= radius; } @Override public double rayCast(Ray2D ray) { final double divisor = ray.getDirection().getX()*ray.getDirection().getX()+ray.getDirection().getY()*ray.getDirection().getY(); if(Util.compareDoubles(divisor,0.0d)) return Double.POSITIVE_INFINITY; final double squareRoot = Math.sqrt(ray.getDirection().getY()*(ray.getDirection().getY()*(radius*radius+ray.getStart().getX()*(2*center.getX()-ray.getStart().getX())-center.getX()*center.getX())+2*ray.getDirection().getX()*(ray.getStart().getX()*(ray.getStart().getY()-center.getY())+center.getX()*(center.getY()-ray.getStart().getY())))+ray.getDirection().getX()*ray.getDirection().getX()*(radius*radius+ray.getStart().getY()*(2*center.getY()-ray.getStart().getY())-center.getY()*center.getY())); if(Util.compareDoubles(squareRoot,Double.NaN)) return Double.POSITIVE_INFINITY; final double factors = ray.getDirection().getX()*(center.getX()-ray.getStart().getX())+ray.getDirection().getY()*(center.getY()-ray.getStart().getY()); final double result = (factors-Math.abs(squareRoot))/divisor; if(result >= 0) return ray.getDirection().length() * result; return Double.POSITIVE_INFINITY; } @Override public Rect2D getBounds() { return new Rect2D(center.getX()-radius, center.getY()-radius, center.getX()+radius, center.getY()+radius); } @Override public IGeometric2D transform(TransformMatrix2D matrix) { final Point2D centerNew = matrix.multiply(center); final Point2D maxXNew = matrix.multiply(new Point2D(center.getX()+radius,center.getY())); final Point2D maxYNew = matrix.multiply(new Point2D(center.getX(),center.getY()+radius)); final Vector2D vectorXNew = centerNew.vec(maxXNew); final Vector2D vectorYNew = centerNew.vec(maxYNew); final double radiusXNew = vectorXNew.length(); final double radiusYNew = vectorYNew.length(); if(Util.compareDoubles(radiusXNew, radiusYNew)) { //Transform let this circle stay a circle. return new Circle2D(centerNew,radiusXNew); } if(Util.compareDoubles(maxXNew.getY(),centerNew.getY()) && Util.compareDoubles(maxYNew.getX(),centerNew.getX())) { //Transform let this circle become a ellipse, but it is not rotated. return new Ellipse2D(centerNew,radiusXNew,radiusYNew); } //Transform let this circle become a rotated ellipse. return new Ellipse2D(centerNew,vectorXNew,vectorYNew); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy