/** * Creates a 2D polygon with the provided vertices. * * @param vertices * List of vertices which will be copied. Each vertex should have * a position in 2D space, positions beyond 2D will be ignored. */ public DefaultWritablePolygon2D( final List< ? extends RealLocalizable > vertices ) { // Regions.getBoundsReal(...) could create an interval with n > 2, if // the first vertex had n > 2. Instead create 2D interval, and then set // min/max. super( 2 ); x = new VertexList( vertices.size() ); y = new VertexList( vertices.size() ); populateXY( vertices ); }
protected void makeRoom( final int offset, final int count ) { ensureCapacity( size() + count ); System.arraycopy( _data, offset, _data, offset + count, size() - offset ); _pos += count; } }
@Override public boolean test( final RealLocalizable localizable ) { // check edges, this needs to be done first because pnpoly has // unknown edge behavior boolean edge = false; final double[] pt1 = new double[ 2 ]; final double[] pt2 = new double[ 2 ]; for ( int i = 0; i < x.size(); i++ ) { pt1[ 0 ] = x.get( i ); pt1[ 1 ] = y.get( i ); // 1e-15 is for error caused by double precision if ( i == x.size() - 1 ) { pt2[ 0 ] = x.get( 0 ); pt2[ 1 ] = y.get( 0 ); } else { pt2[ 0 ] = x.get( i + 1 ); pt2[ 1 ] = y.get( i + 1 ); } edge = GeomMaths.lineContains( pt1, pt2, localizable, 2 ); if ( edge ) return true; } return GeomMaths.pnpoly( x, y, localizable ); }
/** * Creates a 2D polygon with vertices at the provided x, y coordinates. If * the x and y arrays have unequal lengths, the longer array will be * truncated. * * @param x * X coordinates of the vertices which will be copied * @param y * Y coordinates of the vertices which will be copied */ public DefaultWritablePolygon2D( final double[] x, final double[] y ) { super( GeomMaths.getBoundsReal( x, y ) ); if ( x.length == y.length ) { this.x = new VertexList( x ); this.y = new VertexList( y ); } else { final int l = x.length < y.length ? x.length : y.length; this.x = new VertexList( l ); this.x.add( x, 0, l ); this.y = new VertexList( l ); this.y.add( y, 0, l ); } }
@Override public boolean test( final RealLocalizable localizable ) { // check edges, this needs to be done first because pnpoly has // unknown edge behavior boolean edge = false; final double[] pt1 = new double[ 2 ]; final double[] pt2 = new double[ 2 ]; for ( int i = 0; i < x.size(); i++ ) { pt1[ 0 ] = x.get( i ); pt1[ 1 ] = y.get( i ); if ( i == x.size() - 1 ) { pt2[ 0 ] = x.get( 0 ); pt2[ 1 ] = y.get( 0 ); } else { pt2[ 0 ] = x.get( i + 1 ); pt2[ 1 ] = y.get( i + 1 ); } edge = GeomMaths.lineContains( pt1, pt2, localizable, 2 ); if ( edge ) return false; } // not on edge, check inside return GeomMaths.pnpoly( x, y, localizable ); }
@Override public void addVertices( int index, Collection< RealLocalizable > vertices ) { x.makeRoom( index, vertices.size() ); y.makeRoom( index, vertices.size() ); int offset = index; for ( final RealLocalizable vertex : vertices ) { x.setQuick( offset, vertex.getDoublePosition( 0 ) ); y.setQuick( offset, vertex.getDoublePosition( 1 ) ); offset++; } final RealInterval bounds = GeomMaths.getBoundsReal( vertices ); expandMinMax( bounds.realMin( 0 ), bounds.realMin( 1 ), bounds.realMax( 0 ), bounds.realMax( 1 ) ); }
@Override public int numVertices() { return x.size(); }
/** * If the given vertex has more than 2 dimensions, the higher dimensions * will be ignored. */ @Override public void addVertex( final int index, final RealLocalizable vertex ) { final double px = vertex.getDoublePosition( 0 ); final double py = vertex.getDoublePosition( 1 ); x.insert( index, px ); y.insert( index, py ); expandMinMax(px, py, px, py); }