[Arakhnę-Dev] [411] * Add intersection test between a Shape and a Path or a PathIterator. |
[ Thread Index |
Date Index
| More arakhne.org/dev Archives
]
Revision: 411
Author: galland
Date: 2013-04-05 12:09:47 +0200 (Fri, 05 Apr 2013)
Log Message:
-----------
* Add intersection test between a Shape and a Path or a PathIterator.
Modified Paths:
--------------
trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/AbstractShape2f.java
trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Circle2f.java
trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Ellipse2f.java
trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Rectangle2f.java
trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/RoundRectangle2f.java
trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Shape2f.java
Modified: trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/AbstractShape2f.java
===================================================================
--- trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/AbstractShape2f.java 2013-04-05 10:07:45 UTC (rev 410)
+++ trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/AbstractShape2f.java 2013-04-05 10:09:47 UTC (rev 411)
@@ -69,7 +69,7 @@
public final PathIterator2f getPathIterator() {
return getPathIterator(null);
}
-
+
/** {@inheritDoc}
*/
@Override
Modified: trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Circle2f.java
===================================================================
--- trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Circle2f.java 2013-04-05 10:07:45 UTC (rev 410)
+++ trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Circle2f.java 2013-04-05 10:09:47 UTC (rev 411)
@@ -22,6 +22,7 @@
import java.util.NoSuchElementException;
+import org.arakhne.afc.math.MathConstants;
import org.arakhne.afc.math.MathUtil;
import org.arakhne.afc.math.generic.PathWindingRule;
import org.arakhne.afc.math.generic.Point2D;
@@ -459,6 +460,21 @@
s.getX1(), s.getY1(),
s.getX2(), s.getY2());
}
+
+ @Override
+ public boolean intersects(Path2f s) {
+ return intersects(s.getPathIterator());
+ }
+
+ @Override
+ public boolean intersects(PathIterator2f s) {
+ int mask = (s.getWindingRule() == PathWindingRule.NON_ZERO ? -1 : 2);
+ int crossings = Path2f.computeCrossingsFromCircle(
+ getPathIterator(),
+ getX(), getY(), getRadius());
+ return (crossings == MathConstants.SHAPE_INTERSECTS ||
+ (crossings & mask) != 0);
+ }
@Override
public String toString() {
Modified: trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Ellipse2f.java
===================================================================
--- trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Ellipse2f.java 2013-04-05 10:07:45 UTC (rev 410)
+++ trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Ellipse2f.java 2013-04-05 10:09:47 UTC (rev 411)
@@ -22,6 +22,7 @@
import java.util.NoSuchElementException;
+import org.arakhne.afc.math.MathConstants;
import org.arakhne.afc.math.MathUtil;
import org.arakhne.afc.math.generic.PathWindingRule;
import org.arakhne.afc.math.generic.Point2D;
@@ -502,6 +503,21 @@
}
@Override
+ public boolean intersects(Path2f s) {
+ return intersects(s.getPathIterator());
+ }
+
+ @Override
+ public boolean intersects(PathIterator2f s) {
+ int mask = (s.getWindingRule() == PathWindingRule.NON_ZERO ? -1 : 2);
+ int crossings = Path2f.computeCrossingsFromEllipse(
+ getPathIterator(),
+ getMinX(), getMinY(), getWidth(), getHeight());
+ return (crossings == MathConstants.SHAPE_INTERSECTS ||
+ (crossings & mask) != 0);
+ }
+
+ @Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("["); //$NON-NLS-1$
Modified: trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Rectangle2f.java
===================================================================
--- trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Rectangle2f.java 2013-04-05 10:07:45 UTC (rev 410)
+++ trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Rectangle2f.java 2013-04-05 10:09:47 UTC (rev 411)
@@ -22,6 +22,7 @@
import java.util.NoSuchElementException;
+import org.arakhne.afc.math.MathConstants;
import org.arakhne.afc.math.MathUtil;
import org.arakhne.afc.math.generic.PathWindingRule;
import org.arakhne.afc.math.generic.Point2D;
@@ -231,12 +232,12 @@
*/
public static boolean containsRectangleRectangle(float rx1, float ry1, float rwidth1, float rheight1, float rx2, float ry2, float rwidth2, float rheight2) {
if (rwidth1<=0f || rwidth2<=0f || rheight1<=0 || rheight2<=0f) {
- return false;
- }
- return (rx2 >= rx1 &&
- ry2 >= ry1 &&
- (rx2 + rwidth2) <= rx1 + rwidth1 &&
- (ry2 + rheight2) <= ry1 + rheight1);
+ return false;
+ }
+ return (rx2 >= rx1 &&
+ ry2 >= ry1 &&
+ (rx2 + rwidth2) <= rx1 + rwidth1 &&
+ (ry2 + rheight2) <= ry1 + rheight1);
}
/** Compute the intersection of r1 and r2.
@@ -378,7 +379,7 @@
&&
(y>=getMinY() && y<=getMaxY());
}
-
+
@Override
public boolean contains(Rectangle2f r) {
return containsRectangleRectangle(
@@ -535,7 +536,7 @@
getMaxX(), getMaxY(),
transform);
}
-
+
@Override
public boolean equals(Object obj) {
if (obj == this) {
@@ -598,6 +599,23 @@
}
@Override
+ public boolean intersects(Path2f s) {
+ return intersects(s.getPathIterator());
+ }
+
+ @Override
+ public boolean intersects(PathIterator2f s) {
+ // Copied from AWT API
+ if (isEmpty()) return false;
+ int mask = (s.getWindingRule() == PathWindingRule.NON_ZERO ? -1 : 2);
+ int crossings = Path2f.computeCrossingsFromRect(
+ getPathIterator(),
+ getMinX(), getMinY(), getMaxX(), getMaxY());
+ return (crossings == MathConstants.SHAPE_INTERSECTS ||
+ (crossings & mask) != 0);
+ }
+
+ @Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("["); //$NON-NLS-1$
@@ -611,7 +629,7 @@
b.append("]"); //$NON-NLS-1$
return b.toString();
}
-
+
/** Move this rectangle to avoid collision
* with the reference rectangle.
*
@@ -654,7 +672,7 @@
getMinY()+dy,
getWidth(),
getHeight());
-
+
return new Vector2f(dx, dy);
}
@@ -668,7 +686,7 @@
public Vector2D avoidCollisionWith(Rectangle2f reference, Vector2D displacementDirection) {
if (displacementDirection==null || displacementDirection.lengthSquared()==0f)
return avoidCollisionWith(reference);
-
+
float dx1 = reference.getMaxX() - getMinX();
float dx2 = reference.getMinX() - getMaxX();
float dy1 = reference.getMaxY() - getMinY();
@@ -678,9 +696,9 @@
float absdx2 = Math.abs(dx2);
float absdy1 = Math.abs(dy1);
float absdy2 = Math.abs(dy2);
-
+
float dx, dy;
-
+
if (displacementDirection.getX()<0) {
dx = -Math.min(absdx1, absdx2);
}
@@ -713,13 +731,13 @@
* @mavenartifactid $ArtifactId$
*/
private static class CopyPathIterator implements PathIterator2f {
-
+
private final float x1;
private final float y1;
private final float x2;
private final float y2;
private int index = 0;
-
+
/**
* @param x1
* @param y1
@@ -783,7 +801,7 @@
public PathWindingRule getWindingRule() {
return PathWindingRule.NON_ZERO;
}
-
+
}
/** Iterator on the path elements of the rectangle.
@@ -794,17 +812,17 @@
* @mavenartifactid $ArtifactId$
*/
private static class TransformPathIterator implements PathIterator2f {
-
+
private final Transform2D transform;
private final float x1;
private final float y1;
private final float x2;
private final float y2;
private int index = 0;
-
+
private final Point2D p1 = new Point2f();
private final Point2D p2 = new Point2f();
-
+
/**
* @param x1
* @param y1
@@ -894,7 +912,7 @@
public PathWindingRule getWindingRule() {
return PathWindingRule.NON_ZERO;
}
-
+
}
}
\ No newline at end of file
Modified: trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/RoundRectangle2f.java
===================================================================
--- trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/RoundRectangle2f.java 2013-04-05 10:07:45 UTC (rev 410)
+++ trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/RoundRectangle2f.java 2013-04-05 10:09:47 UTC (rev 411)
@@ -116,7 +116,7 @@
private static final float C = (float)Math.sqrt(1f + B * B) - 1f + A;
private static final float CV = 4f / 3f * A * B / C;
private static final float ACV = (1f - CV) / 2f;
-
+
/** For each array:
* 4 values for each point {v0, v1, v2, v3}:
* point = (x + v0 * w + v1 * arcWidth,
@@ -142,7 +142,7 @@
0f, 0f, 0f, .5f },
{},
};
-
+
/** Types of path elements for the round rectangle.
*/
static PathElementType TYPES[] = {
@@ -154,7 +154,7 @@
PathElementType.CLOSE,
};
-
+
/** Width of the arcs at the corner of the box. */
protected float arcWidth;
/** Height of the arcs at the corner of the box. */
@@ -191,7 +191,7 @@
this.arcWidth = arcWidth;
this.arcHeight = arcHeight;
}
-
+
@Override
public void clear() {
this.arcHeight = this.arcWidth = 0f;
@@ -259,7 +259,7 @@
getMinX(), getMinY(), getWidth(), getHeight(), getArcWidth(), getArcHeight(),
x, y);
}
-
+
@Override
public boolean contains(Rectangle2f r) {
return containsRoundRectangleRectangle(
@@ -370,7 +370,7 @@
getArcWidth(), getArcHeight(),
transform);
}
-
+
@Override
public boolean equals(Object obj) {
if (obj == this) {
@@ -442,6 +442,23 @@
}
@Override
+ public boolean intersects(Path2f s) {
+ return intersects(s.getPathIterator());
+ }
+
+ @Override
+ public boolean intersects(PathIterator2f s) {
+ // Copied from AWT API
+ if (isEmpty()) return false;
+ int mask = (s.getWindingRule() == PathWindingRule.NON_ZERO ? -1 : 2);
+ int crossings = Path2f.computeCrossingsFromRect(
+ getPathIterator(),
+ getMinX(), getMinY(), getMaxX(), getMaxY());
+ return (crossings == MathConstants.SHAPE_INTERSECTS ||
+ (crossings & mask) != 0);
+ }
+
+ @Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("["); //$NON-NLS-1$
@@ -468,7 +485,7 @@
* @mavenartifactid $ArtifactId$
*/
private static class CopyPathIterator implements PathIterator2f {
-
+
private final float x;
private final float y;
private final float w;
@@ -476,9 +493,9 @@
private final float aw;
private final float ah;
private int index = 0;
-
+
private float moveX, moveY, lastX, lastY;
-
+
/**
* @param x
* @param y
@@ -503,7 +520,7 @@
public boolean hasNext() {
return this.index<TYPES.length;
}
-
+
@Override
public PathElement2f next() {
if (this.index>=TYPES.length) throw new NoSuchElementException();
@@ -514,23 +531,23 @@
float ctrls[] = CTRL_PTS[idx];
float ix, iy;
float ctrlx1, ctrly1, ctrlx2, ctrly2;
-
+
switch(type) {
case MOVE_TO:
this.moveX = this.lastX = this.x + ctrls[0] * this.w + ctrls[1] * this.aw;
this.moveY = this.lastY = this.y + ctrls[2] * this.h + ctrls[3] * this.ah;
- element = new PathElement2f.MovePathElement2f(
- this.lastX, this.lastY);
- break;
+ element = new PathElement2f.MovePathElement2f(
+ this.lastX, this.lastY);
+ break;
case LINE_TO:
ix = this.lastX;
iy = this.lastY;
this.lastX = this.x + ctrls[0] * this.w + ctrls[1] * this.aw;
this.lastY = this.y + ctrls[2] * this.h + ctrls[3] * this.ah;
- element = new PathElement2f.LinePathElement2f(
- ix, iy,
- this.lastX, this.lastY);
- break;
+ element = new PathElement2f.LinePathElement2f(
+ ix, iy,
+ this.lastX, this.lastY);
+ break;
case CURVE_TO:
ix = this.lastX;
iy = this.lastY;
@@ -540,30 +557,30 @@
ctrly2 = this.y + ctrls[6] * this.h + ctrls[7] * this.ah;
this.lastX = this.x + ctrls[8] * this.w + ctrls[9] * this.aw;
this.lastY = this.y + ctrls[10] * this.h + ctrls[11] * this.ah;
- element = new PathElement2f.CurvePathElement2f(
- ix, iy,
- ctrlx1, ctrly1,
- ctrlx2, ctrly2,
- this.lastX, this.lastY);
- break;
+ element = new PathElement2f.CurvePathElement2f(
+ ix, iy,
+ ctrlx1, ctrly1,
+ ctrlx2, ctrly2,
+ this.lastX, this.lastY);
+ break;
case CLOSE:
ix = this.lastX;
iy = this.lastY;
this.lastX = this.moveX;
this.lastY = this.moveY;
- element = new PathElement2f.ClosePathElement2f(
- ix, iy,
- this.lastX, this.lastY);
+ element = new PathElement2f.ClosePathElement2f(
+ ix, iy,
+ this.lastX, this.lastY);
break;
case QUAD_TO:
default:
throw new NoSuchElementException();
}
-
+
assert(element!=null);
-
+
++this.index;
-
+
return element;
}
@@ -576,7 +593,7 @@
public PathWindingRule getWindingRule() {
return PathWindingRule.NON_ZERO;
}
-
+
}
/** Iterator on the path elements of the rectangle.
@@ -587,7 +604,7 @@
* @mavenartifactid $ArtifactId$
*/
private static class TransformPathIterator implements PathIterator2f {
-
+
private final Transform2D transform;
private final float x;
private final float y;
@@ -596,12 +613,12 @@
private final float aw;
private final float ah;
private int index = 0;
-
+
private float moveX, moveY;
private final Point2D last = new Point2f();
private final Point2D ctrl1 = new Point2f();
private final Point2D ctrl2 = new Point2f();
-
+
/**
* @param x
* @param y
@@ -628,7 +645,7 @@
public boolean hasNext() {
return this.index<TYPES.length;
}
-
+
@Override
public PathElement2f next() {
if (this.index>=TYPES.length) throw new NoSuchElementException();
@@ -638,16 +655,16 @@
PathElementType type = TYPES[idx];
float ctrls[] = CTRL_PTS[idx];
float ix, iy;
-
+
switch(type) {
case MOVE_TO:
this.moveX = this.x + ctrls[0] * this.w + ctrls[1] * this.aw;
this.moveY = this.y + ctrls[2] * this.h + ctrls[3] * this.ah;
this.last.set(this.moveX, this.moveY);
this.transform.transform(this.last);
- element = new PathElement2f.MovePathElement2f(
- this.last.getX(), this.last.getY());
- break;
+ element = new PathElement2f.MovePathElement2f(
+ this.last.getX(), this.last.getY());
+ break;
case LINE_TO:
ix = this.last.getX();
iy = this.last.getY();
@@ -655,16 +672,16 @@
this.x + ctrls[0] * this.w + ctrls[1] * this.aw,
this.y + ctrls[2] * this.h + ctrls[3] * this.ah);
this.transform.transform(this.last);
- element = new PathElement2f.LinePathElement2f(
- ix, iy,
- this.last.getX(), this.last.getY());
- break;
+ element = new PathElement2f.LinePathElement2f(
+ ix, iy,
+ this.last.getX(), this.last.getY());
+ break;
case CURVE_TO:
ix = this.last.getX();
iy = this.last.getY();
this.ctrl1.set(
- this.x + ctrls[0] * this.w + ctrls[1] * this.aw,
- this.y + ctrls[2] * this.h + ctrls[3] * this.ah);
+ this.x + ctrls[0] * this.w + ctrls[1] * this.aw,
+ this.y + ctrls[2] * this.h + ctrls[3] * this.ah);
this.transform.transform(this.ctrl1);
this.ctrl2.set(
this.x + ctrls[4] * this.w + ctrls[5] * this.aw,
@@ -674,30 +691,30 @@
this.x + ctrls[8] * this.w + ctrls[9] * this.aw,
this.y + ctrls[10] * this.h + ctrls[11] * this.ah);
this.transform.transform(this.last);
- element = new PathElement2f.CurvePathElement2f(
- ix, iy,
- this.ctrl1.getX(), this.ctrl1.getY(),
- this.ctrl2.getX(), this.ctrl2.getY(),
- this.last.getX(), this.last.getY());
- break;
+ element = new PathElement2f.CurvePathElement2f(
+ ix, iy,
+ this.ctrl1.getX(), this.ctrl1.getY(),
+ this.ctrl2.getX(), this.ctrl2.getY(),
+ this.last.getX(), this.last.getY());
+ break;
case CLOSE:
ix = this.last.getX();
iy = this.last.getY();
this.last.set(this.moveX, this.moveY);
this.transform.transform(this.last);
- element = new PathElement2f.ClosePathElement2f(
- ix, iy,
- this.last.getX(), this.last.getY());
+ element = new PathElement2f.ClosePathElement2f(
+ ix, iy,
+ this.last.getX(), this.last.getY());
break;
case QUAD_TO:
default:
throw new NoSuchElementException();
}
-
+
assert(element!=null);
-
+
++this.index;
-
+
return element;
}
@@ -710,7 +727,7 @@
public PathWindingRule getWindingRule() {
return PathWindingRule.NON_ZERO;
}
-
+
}
}
\ No newline at end of file
Modified: trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Shape2f.java
===================================================================
--- trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Shape2f.java 2013-04-05 10:07:45 UTC (rev 410)
+++ trunk/math/src/main/java/org/arakhne/afc/math/continous/object2d/Shape2f.java 2013-04-05 10:09:47 UTC (rev 411)
@@ -158,4 +158,20 @@
*/
public boolean intersects(Segment2f s);
+ /** Replies if this shape is intersecting the given path.
+ *
+ * @param s
+ * @return <code>true</code> if this shape is intersecting the given path;
+ * <code>false</code> if there is no intersection.
+ */
+ public boolean intersects(Path2f s);
+
+ /** Replies if this shape is intersecting the given path.
+ *
+ * @param s
+ * @return <code>true</code> if this shape is intersecting the given path;
+ * <code>false</code> if there is no intersection.
+ */
+ public boolean intersects(PathIterator2f s);
+
}
\ No newline at end of file