Skip to content

Commit

Permalink
Improved Polygon performance by using dirty bit mechanism.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomcashman committed May 22, 2016
1 parent 7c2f727 commit 0a26d2b
Showing 1 changed file with 72 additions and 70 deletions.
142 changes: 72 additions & 70 deletions core/src/main/java/org/mini2Dx/core/geom/Polygon.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public class Polygon extends Shape {
private ShortArray triangles;
private float trackedRotation = 0f;
private boolean isRectangle;
private boolean minMaxDirty = true;
private boolean trianglesDirty = true;

/**
* Constructor. Note that vertices must be in a clockwise order for
Expand All @@ -51,8 +53,6 @@ public Polygon(float[] vertices) {
polygon = new com.badlogic.gdx.math.Polygon(vertices);
polygon.setOrigin(vertices[0], vertices[1]);
triangulator = new EarClippingTriangulator();
computeTriangles(polygon.getTransformedVertices());
calculateMinMaxXY(polygon.getTransformedVertices());
getNumberOfSides();
}

Expand Down Expand Up @@ -108,36 +108,6 @@ private void clearTotalSidesCache() {
totalSidesCache = -1;
}

private void computeTriangles(float[] vertices) {
triangles = triangulator.computeTriangles(vertices);
}

private void calculateMinMaxXY(float[] vertices) {
int minXIndex = 0;
int minYIndex = 1;
int maxXIndex = 0;
int maxYIndex = 1;
for (int i = 2; i < vertices.length; i += 2) {
if (vertices[i] < vertices[minXIndex]) {
minXIndex = i;
}
if (vertices[i + 1] < vertices[minYIndex]) {
minYIndex = i + 1;
}
if (vertices[i] > vertices[maxXIndex]) {
maxXIndex = i;
}
if (vertices[i + 1] > vertices[maxYIndex]) {
maxYIndex = i + 1;
}

}
this.minX = vertices[minXIndex];
this.minY = vertices[minYIndex];
this.maxX = vertices[maxXIndex];
this.maxY = vertices[maxYIndex];
}

protected boolean triangleContains(float x, float y, float p1x, float p1y, float p2x, float p2y, float p3x,
float p3y) {
boolean b1, b2, b3;
Expand Down Expand Up @@ -200,6 +170,8 @@ public boolean intersects(Shape shape) {
* @return True if the two {@link Polygon}s intersect
*/
public boolean intersects(Polygon polygon) {
minMaxDirtyCheck();
polygon.minMaxDirtyCheck();
if (isRectangle && polygon.isRectangle) {
boolean xAxisOverlaps = true;
boolean yAxisOverlaps = true;
Expand Down Expand Up @@ -267,6 +239,7 @@ public boolean intersects(Rectangle rectangle) {

public boolean intersects(Circle circle) {
if (isRectangle) {
minMaxDirtyCheck();
float closestX = circle.getX();
float closestY = circle.getY();

Expand Down Expand Up @@ -357,20 +330,9 @@ public void addPoint(float x, float y) {

polygon.translate(-polygon.getX(), -polygon.getY());
polygon.setVertices(newVertices);

computeTriangles(newVertices);

clearTotalSidesCache();

if (x > maxX) {
maxX = x;
} else if (x < minX) {
minX = x;
}
if (y > maxY) {
maxY = y;
} else if (y < minY) {
minY = y;
}
setDirty();
}

/**
Expand All @@ -394,8 +356,7 @@ private void removePoint(int i) {
}
polygon.translate(-polygon.getX(), -polygon.getY());
polygon.setVertices(newVertices);
computeTriangles(newVertices);
calculateMinMaxXY(newVertices);
setDirty();
clearTotalSidesCache();
}

Expand Down Expand Up @@ -460,9 +421,8 @@ public void setVertices(float[] vertices) {
polygon.setVertices(vertices);
trackedRotation = 0f;

calculateMinMaxXY(vertices);
computeTriangles(vertices);
clearTotalSidesCache();
setDirty();
}

public void setVertices(Vector2[] vertices) {
Expand Down Expand Up @@ -490,9 +450,7 @@ public void setRotationAround(float centerX, float centerY, float degrees) {
polygon.setOrigin(centerX, centerY);
polygon.setRotation(degrees - trackedRotation);
trackedRotation = degrees;

calculateMinMaxXY(polygon.getTransformedVertices());
computeTriangles(polygon.getTransformedVertices());
setDirty();
}

@Override
Expand All @@ -503,9 +461,7 @@ public void rotateAround(float centerX, float centerY, float degrees) {
polygon.setOrigin(centerX, centerY);
polygon.setVertices(vertices);
polygon.rotate(degrees);

calculateMinMaxXY(polygon.getTransformedVertices());
computeTriangles(polygon.getTransformedVertices());
setDirty();
}

/**
Expand Down Expand Up @@ -556,6 +512,7 @@ public float getY(int index) {
* @return The left-most x coordinate
*/
public float getMinX() {
minMaxDirtyCheck();
return minX;
}

Expand All @@ -565,6 +522,7 @@ public float getMinX() {
* @return The up-most y coordinate
*/
public float getMinY() {
minMaxDirtyCheck();
return minY;
}

Expand All @@ -574,6 +532,7 @@ public float getMinY() {
* @return The right-most x coordinate
*/
public float getMaxX() {
minMaxDirtyCheck();
return maxX;
}

Expand All @@ -583,6 +542,7 @@ public float getMaxX() {
* @return The bottom-most y coordinate
*/
public float getMaxY() {
minMaxDirtyCheck();
return maxY;
}

Expand All @@ -593,6 +553,7 @@ public float getMaxY() {
* @return Array of triangle indices
*/
public ShortArray getTriangles() {
trianglesDirtyCheck();
return triangles;
}

Expand Down Expand Up @@ -622,9 +583,7 @@ public void setX(float x) {
}
polygon.setOrigin(x, getY());
polygon.setVertices(vertices);

calculateMinMaxXY(vertices);
computeTriangles(vertices);
setDirty();
}

@Override
Expand All @@ -637,9 +596,7 @@ public void setY(float y) {
}
polygon.setOrigin(getX(), y);
polygon.setVertices(vertices);

calculateMinMaxXY(vertices);
computeTriangles(vertices);
setDirty();
}

@Override
Expand All @@ -654,20 +611,16 @@ public void set(float x, float y) {
}
polygon.setOrigin(x, y);
polygon.setVertices(vertices);

calculateMinMaxXY(vertices);
computeTriangles(vertices);
setDirty();
}

public void set(Polygon polygon) {
this.polygon.setOrigin(polygon.polygon.getOriginX(), polygon.polygon.getOriginY());
this.polygon.setVertices(polygon.polygon.getTransformedVertices());
this.polygon.setRotation(0f);
this.trackedRotation = polygon.trackedRotation;

calculateMinMaxXY(this.polygon.getTransformedVertices());
computeTriangles(this.polygon.getTransformedVertices());
clearTotalSidesCache();
setDirty();
}

@Override
Expand All @@ -680,9 +633,7 @@ public void translate(float translateX, float translateY) {
}
polygon.setOrigin(vertices[0], vertices[1]);
polygon.setVertices(vertices);

calculateMinMaxXY(vertices);
computeTriangles(vertices);
setDirty();
}

@Override
Expand All @@ -699,6 +650,57 @@ public boolean isCircle() {
public Polygon getPolygon() {
return this;
}

private void setDirty() {
minMaxDirty = true;
trianglesDirty = true;
}

private void minMaxDirtyCheck() {
if(!minMaxDirty) {
return;
}
calculateMinMaxXY(polygon.getTransformedVertices());
minMaxDirty = false;
}

private void trianglesDirtyCheck() {
if(!trianglesDirty) {
return;
}
computeTriangles(polygon.getTransformedVertices());
trianglesDirty = false;
}

private void computeTriangles(float[] vertices) {
triangles = triangulator.computeTriangles(vertices);
}

private void calculateMinMaxXY(float[] vertices) {
int minXIndex = 0;
int minYIndex = 1;
int maxXIndex = 0;
int maxYIndex = 1;
for (int i = 2; i < vertices.length; i += 2) {
if (vertices[i] < vertices[minXIndex]) {
minXIndex = i;
}
if (vertices[i + 1] < vertices[minYIndex]) {
minYIndex = i + 1;
}
if (vertices[i] > vertices[maxXIndex]) {
maxXIndex = i;
}
if (vertices[i + 1] > vertices[maxYIndex]) {
maxYIndex = i + 1;
}

}
this.minX = vertices[minXIndex];
this.minY = vertices[minYIndex];
this.maxX = vertices[maxXIndex];
this.maxY = vertices[maxYIndex];
}

@Override
public String toString() {
Expand Down

0 comments on commit 0a26d2b

Please sign in to comment.