[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


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/