package org.osm2world.core.math; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * a three-dimensional polygon */ public class PolygonXYZ { /** polygon vertices; first and last vertex are equal */ private final List<VectorXYZ> vertexLoop; /** * @param vertexLoop vertices defining the polygon; * first and last vertex must be equal */ public PolygonXYZ(List<VectorXYZ> vertexLoop) { if (!vertexLoop.get(0).equals(vertexLoop.get(vertexLoop.size() - 1))) { throw new IllegalArgumentException("first and last vertex must be equal"); } this.vertexLoop = vertexLoop; } /** * returns the polygon's vertices. * Unlike {@link #getVertexLoop()}, there is no duplication * of the first/last vertex. */ public List<VectorXYZ> getVertices() { return vertexLoop.subList(0, vertexLoop.size()-1); } /** * returns the polygon's vertices. First and last vertex are equal. */ public List<VectorXYZ> getVertexLoop() { return vertexLoop; } /** * returns the number of vertices in this polygon. * The duplicated first/last vertex is <em>not</em> counted twice, * so the result is equivalent to {@link #getVertices()}.size(). */ public int size() { return vertexLoop.size()-1; } //TODO (code duplication): common polygon supertype? public List<LineSegmentXYZ> getSegments() { List<LineSegmentXYZ> segments = new ArrayList<LineSegmentXYZ>(vertexLoop.size()); for (int i=0; i+1 < vertexLoop.size(); i++) { segments.add(new LineSegmentXYZ(vertexLoop.get(i), vertexLoop.get(i+1))); } return segments; } public PolygonXZ getXZPolygon() { List<VectorXZ> verticesXZ = new ArrayList<VectorXZ>(vertexLoop.size()); for (VectorXYZ vertex : vertexLoop) { verticesXZ.add(vertex.xz()); } return new PolygonXZ(verticesXZ); } /** * caller must check whether flattening will result in a simple planar polygon */ public SimplePolygonXZ getSimpleXZPolygon() { List<VectorXZ> verticesXZ = new ArrayList<VectorXZ>(vertexLoop.size()); for (VectorXYZ vertex : vertexLoop) { verticesXZ.add(vertex.xz()); } return new SimplePolygonXZ(verticesXZ); } /** * returns a triangle with the same vertices as this polygon. * Requires that the polygon is triangular! */ public TriangleXYZ asTriangleXYZ() { if (vertexLoop.size() != 4) { throw new InvalidGeometryException("attempted creation of triangle " + "from polygon with vertex loop of size " + vertexLoop.size() + ": " + vertexLoop); } else { return new TriangleXYZ( vertexLoop.get(0), vertexLoop.get(1), vertexLoop.get(2)); } } /** * returns a reversed version of this polygon. * It consists of the same vertices, but has the other direction. */ public PolygonXYZ reverse() { List<VectorXYZ> newVertexLoop = new ArrayList<VectorXYZ>(vertexLoop); Collections.reverse(newVertexLoop); return new PolygonXYZ(newVertexLoop); } }