org.jbox2d.util.nonconvex
Class Polygon

java.lang.Object
  extended by org.jbox2d.util.nonconvex.Polygon

public class Polygon
extends Object

Author:
ewjordan

Field Summary
static boolean B2_POLYGON_REPORT_ERRORS
           
 int nVertices
           
 float[] x
           
 float[] y
           
 
Constructor Summary
Polygon()
           
Polygon(float[] _x, float[] _y)
           
Polygon(float[] _x, float[] _y, int nVert)
           
Polygon(org.jbox2d.util.nonconvex.Triangle t)
           
Polygon(Vec2[] v)
           
Polygon(Vec2[] v, int nVert)
           
 
Method Summary
 void addTo(PolygonDef pd)
          Adds this polygon to a PolyDef.
static Polygon convexHull(float[] cloudX, float[] cloudY, int nVert)
           
static Polygon convexHull(Vec2[] v, int nVert)
          Find the convex hull of a point cloud using "Gift-wrap" algorithm - start with an extremal point, and walk around the outside edge by testing angles.
static int decomposeConvex(Polygon p, Polygon[] results, int maxPolys)
          Decomposes a non-convex polygon into a number of convex polygons, up to maxPolys (remaining pieces are thrown out, but the total number is returned, so the return value can be greater than maxPolys).
static void decomposeConvexAndAddTo(Polygon p, Body bd, PolygonDef prototype)
          Decomposes a polygon into convex polygons and adds all pieces to a b2BodyDef using a prototype b2PolyDef.
 Vec2[] getVertexVecs()
           
 boolean isConvex()
          Assuming the polygon is simple, checks if it is convex.
 boolean isSimple()
           
 boolean isUsable()
           
 boolean isUsable(boolean printErrors)
          Checks if polygon is valid for use in Box2d engine.
static Vec2 polyCentroid(Vec2[] vs, int count)
           
static int polygonizeTriangles(org.jbox2d.util.nonconvex.Triangle[] triangulated, int triangulatedLength, Polygon[] polys, int polysLength)
          Turns a list of triangles into a list of convex polygons.
 void print()
           
static void reversePolygon(float[] x, float[] y, int n)
           
static void reversePolygon(Polygon p)
           
 void set(Polygon p)
           
static Polygon traceEdge(Polygon p)
           
static int triangulatePolygon(float[] xv, float[] yv, int vNum, org.jbox2d.util.nonconvex.Triangle[] results)
          Triangulates a polygon using simple ear-clipping algorithm.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

B2_POLYGON_REPORT_ERRORS

public static boolean B2_POLYGON_REPORT_ERRORS

nVertices

public int nVertices

x

public float[] x

y

public float[] y
Constructor Detail

Polygon

public Polygon(float[] _x,
               float[] _y)

Polygon

public Polygon(float[] _x,
               float[] _y,
               int nVert)

Polygon

public Polygon(Vec2[] v)

Polygon

public Polygon(Vec2[] v,
               int nVert)

Polygon

public Polygon(org.jbox2d.util.nonconvex.Triangle t)

Polygon

public Polygon()
Method Detail

getVertexVecs

public Vec2[] getVertexVecs()

set

public void set(Polygon p)

isConvex

public boolean isConvex()
Assuming the polygon is simple, checks if it is convex.


polyCentroid

public static Vec2 polyCentroid(Vec2[] vs,
                                int count)

isUsable

public boolean isUsable(boolean printErrors)
Checks if polygon is valid for use in Box2d engine. Last ditch effort to ensure no invalid polygons are added to world geometry. Performs a full check, for simplicity, convexity, orientation, minimum angle, and volume. This won't be very efficient, and a lot of it is redundant when other tools in this section are used.


isUsable

public boolean isUsable()

isSimple

public boolean isSimple()

addTo

public void addTo(PolygonDef pd)
Adds this polygon to a PolyDef.


triangulatePolygon

public static int triangulatePolygon(float[] xv,
                                     float[] yv,
                                     int vNum,
                                     org.jbox2d.util.nonconvex.Triangle[] results)
Triangulates a polygon using simple ear-clipping algorithm. Returns size of Triangle array unless the polygon can't be triangulated. This should only happen if the polygon self-intersects, though it will not _always_ return null for a bad polygon - it is the caller's responsibility to check for self-intersection, and if it doesn't, it should at least check that the return value is non-null before using. You're warned! Triangles may be degenerate, especially if you have identical points in the input to the algorithm. Check this before you use them. This is totally unoptimized, so for large polygons it should not be part of the simulation loop. Returns: -1 if algorithm fails (self-intersection most likely) 0 if there are not enough vertices to triangulate anything. Number of triangles if triangulation was successful. results will be filled with results - ear clipping always creates vNum - 2 or fewer (due to pinch point polygon snipping), so allocate an array of this size.


polygonizeTriangles

public static int polygonizeTriangles(org.jbox2d.util.nonconvex.Triangle[] triangulated,
                                      int triangulatedLength,
                                      Polygon[] polys,
                                      int polysLength)
Turns a list of triangles into a list of convex polygons. Very simple method - start with a seed triangle, keep adding triangles to it until you can't add any more without making the polygon non-convex. Returns an integer telling how many polygons were created. Will fill polys array up to polysLength entries, which may be smaller or larger than the return value. Takes O(N*P) where P is the number of resultant polygons, N is triangle count. The final polygon list will not necessarily be minimal, though in practice it works fairly well.


reversePolygon

public static void reversePolygon(Polygon p)

reversePolygon

public static void reversePolygon(float[] x,
                                  float[] y,
                                  int n)

decomposeConvex

public static int decomposeConvex(Polygon p,
                                  Polygon[] results,
                                  int maxPolys)
Decomposes a non-convex polygon into a number of convex polygons, up to maxPolys (remaining pieces are thrown out, but the total number is returned, so the return value can be greater than maxPolys). Each resulting polygon will have no more than maxVerticesPerPolygon vertices (set to b2MaxPolyVertices by default, though you can change this). Returns -1 if operation fails (usually due to self-intersection of polygon).


decomposeConvexAndAddTo

public static void decomposeConvexAndAddTo(Polygon p,
                                           Body bd,
                                           PolygonDef prototype)
Decomposes a polygon into convex polygons and adds all pieces to a b2BodyDef using a prototype b2PolyDef. All fields of the prototype are used for every shape except the vertices (friction, restitution, density, filter, etc). If you want finer control, you'll have to add everything by hand. This is the simplest method to add a complicated polygon to a body.


convexHull

public static Polygon convexHull(Vec2[] v,
                                 int nVert)
Find the convex hull of a point cloud using "Gift-wrap" algorithm - start with an extremal point, and walk around the outside edge by testing angles. Runs in O(N*S) time where S is number of sides of resulting polygon. Worst case: point cloud is all vertices of convex polygon -> O(N^2). There may be faster algorithms to do this, should you need one - this is just the simplest. You can get O(N log N) expected time if you try, I think, and O(N) if you restrict inputs to simple polygons. Returns null if number of vertices passed is less than 3. Results should be passed through convex decomposition afterwards to ensure that each shape has few enough points to be used in Box2d. FIXME?: May be buggy with colinear points on hull. Couldn't find a test case that resulted in wrong behavior. If one turns up, the solution is to supplement angle check with an equality resolver that always picks the longer edge. I think the current solution is working, though it sometimes creates an extra edge along a line.


convexHull

public static Polygon convexHull(float[] cloudX,
                                 float[] cloudY,
                                 int nVert)

traceEdge

public static Polygon traceEdge(Polygon p)

print

public void print()