/* * Copyright (C) 2011-2015, Peter Abeles. All Rights Reserved. * * This file is part of Geometric Regression Library (GeoRegression). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package georegression.struct.shapes; import georegression.geometry.UtilPolygons2D_F64; import georegression.metric.Area2D_F64; import georegression.metric.Intersection2D_F64; import georegression.struct.line.LineSegment2D_F64; import georegression.struct.point.Point2D_F64; import org.ddogleg.struct.FastQueue; import java.io.Serializable; /** * Describes a polygon in 2D. * * @author Peter Abeles */ public class Polygon2D_F64 implements Serializable { // vertexes in the polygon public FastQueue<Point2D_F64> vertexes; public Polygon2D_F64( Polygon2D_F64 a ) { vertexes = new FastQueue<Point2D_F64>(a.size(),Point2D_F64.class,true); for (int i = 0; i < a.size(); i++) { vertexes.grow().set(a.get(i)); } } public Polygon2D_F64( int numVertexes ) { vertexes = new FastQueue<Point2D_F64>(numVertexes, Point2D_F64.class,true); vertexes.growArray(numVertexes); vertexes.size = numVertexes; } public Polygon2D_F64( double... points ) { if( points.length % 2 == 1 ) throw new IllegalArgumentException("Expected an even number"); vertexes = new FastQueue<Point2D_F64>(points.length/2,Point2D_F64.class,true); vertexes.growArray(points.length/2); vertexes.size = points.length/2; int count = 0; for (int i = 0; i < points.length; i += 2) { vertexes.data[count++].set( points[i],points[i+1]); } } public Polygon2D_F64() { vertexes = new FastQueue<Point2D_F64>(Point2D_F64.class,true); } public void set( Polygon2D_F64 orig ) { vertexes.resize(orig.size()); for (int i = 0; i < orig.size(); i++) { vertexes.data[i].set( orig.vertexes.data[i]); } } public void set( int index , double x , double y ) { vertexes.data[index].set(x,y); } public Point2D_F64 get( int index ) { return vertexes.data[index]; } public int size() { return vertexes.size(); } public Polygon2D_F64 copy() { return new Polygon2D_F64(this); } /** * Returns the area for simply polygons. Non-self intersecting convex or concave. * @return area */ public double areaSimple() { return Area2D_F64.polygonSimple(this); } /** * Returns true if the point is inside the polygon. Points along the border are ambiguously considered inside * or outside. * * @see Intersection2D_F64#containConcave(Polygon2D_F64, Point2D_F64) * @see Intersection2D_F64#containConcave(Polygon2D_F64, Point2D_F64) * * @param p A point * @return true if inside and false if outside */ public boolean isInside( Point2D_F64 p ) { if( isConvex() ) { return Intersection2D_F64.containConvex(this,p); } else { return Intersection2D_F64.containConcave(this,p); } } /** * true if the order of vertexes is in counter clockwise order. * @return true if ccw or false if cw */ public boolean isCCW() { return UtilPolygons2D_F64.isCCW(vertexes.toList()); } public boolean isConvex() { return UtilPolygons2D_F64.isConvex(this); } public boolean isIdentical( Polygon2D_F64 a , double tol ) { return UtilPolygons2D_F64.isIdentical(this,a,tol); } public boolean isEquivalent( Polygon2D_F64 a , double tol ) { return UtilPolygons2D_F64.isEquivalent(this, a, tol); } public void flip() { UtilPolygons2D_F64.flip(this); } /** * Returns the line/edge defined by vertex index and index+1. * @param index Index of the line * @return A new instance of the line segment. */ public LineSegment2D_F64 getLine( int index , LineSegment2D_F64 storage ) { if( storage == null ) storage = new LineSegment2D_F64(); int j = (index+1)%vertexes.size; storage.a.set(get(index)); storage.b.set(get(j)); return storage; } @Override public String toString() { String out = getClass().getSimpleName()+"{ order "+vertexes.size+" : vertexes [ "; for (int i = 0; i < vertexes.size; i++) { Point2D_F64 p = vertexes.get(i); out += p.x+" , "+p.y+" ; "; } out += " ] }"; return out; } }