aima.core.util.math.geom.shapes.Polyline2D Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aima-core Show documentation
Show all versions of aima-core Show documentation
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 polyline in a two-dimensional Cartesian plot.
* The polyline is represented by a starting point represented by {@link Point2D} and all edges as {@link Vector2D}.
* If the last side ends in the starting point the polyline is a closed polygon.
*
* @author Arno von Borries
* @author Jan Phillip Kretzschmar
* @author Andreas Walscheid
*
*/
public final class Polyline2D implements IGeometric2D {
private final Point2D[] vertexes;
private final Vector2D[] edges;
private final boolean isClosed;
private final Rect2D boundingRect;
/**
* @param vertexes the vertexes of the polyline or polygon.
* @param isClosed true if the sum of the edges is the zero vector.
*/
public Polyline2D(Point2D[] vertexes, boolean isClosed) {
this.vertexes = vertexes;
this.isClosed = isClosed;
final int length = isClosed ? vertexes.length : vertexes.length - 1;
this.edges = new Vector2D[length];
Point2D previousPoint = vertexes[0];
for(int i=1; i vertexes[i].getX() ? vertexes[i].getX() : minX;
minY = minY > vertexes[i].getY() ? vertexes[i].getY() : minY;
maxX = maxX < vertexes[i].getX() ? vertexes[i].getX() : maxX;
maxY = maxY < vertexes[i].getY() ? vertexes[i].getY() : maxY;
}
boundingRect = new Rect2D(minX,minY,maxX,maxY);
}
/**
* @return the starting point of the polyline.
*/
public Point2D[] getVertexes() {
return vertexes;
}
/**
* @return the edges of the polyline.
*/
public Vector2D[] getEdges() {
return edges;
}
/**
* @return true if this polyline is a polygon.
*/
public boolean isClosed() {
return isClosed;
}
@Override
public Point2D randomPoint() {
if(isClosed) {
//Generate random points within the bounding rectangle...
final double minX = boundingRect.getUpperLeft().getX();
final double maxX = boundingRect.getLowerRight().getX();
final double minY = boundingRect.getUpperLeft().getY();
final double maxY = boundingRect.getLowerRight().getY();
Point2D randPoint = new Point2D(Util.generateRandomDoubleBetween(minX, maxX),Util.generateRandomDoubleBetween(minY, maxY));
//...until one is inside the polygon.
while (!isInsideBorder(randPoint)){
randPoint = new Point2D(Util.generateRandomDoubleBetween(minX, maxX),Util.generateRandomDoubleBetween(minY, maxY));
}
return randPoint;
} else {
final int index = Util.randomNumberBetween(0, vertexes.length-2);
final Line2D line = new Line2D(vertexes[index],edges[index]);
return line.randomPoint();
}
}
@Override
public boolean isInside(Point2D point) {
if(!isClosed) return false;
int intersections = 0;
Ray2D pointRay = new Ray2D(point,Vector2D.X_VECTOR);
for (int i=0; i 0) {
final double len2 = (ray.getDirection().getY()*ray.getStart().getX() - ray.getDirection().getY()*vertexes[i].getX() - ray.getDirection().getX()*ray.getStart().getY() + ray.getDirection().getX()*vertexes[i].getY())/divisor;
if(len2 >= 0 && len2 <= 1) result = result > len1 ? len1 : result;
}
} else {
final Vector2D startVec = ray.getStart().vec(vertexes[i]);
if(ray.getDirection().isAbsoluteParallel(startVec)) {
return startVec.length();
} else {
final Point2D endVertex = isClosed && i == edges.length - 1 ? vertexes[0] : vertexes[i+1];
final Vector2D endVec = ray.getStart().vec(endVertex);
if(ray.getDirection().isAbsoluteParallel(endVec)) {
return endVec.length();
}
}
}
}
return result * ray.getDirection().length();
}
@Override
public Rect2D getBounds() {
return boundingRect;
}
@Override
public Polyline2D transform(TransformMatrix2D matrix) {
Point2D[] vertexesNew = new Point2D[vertexes.length];
for(int i=0;i