diff --git a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/OrientedPoint2D.java b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/OrientedPoint2D.java new file mode 100644 index 000000000..9e663cb1c --- /dev/null +++ b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/OrientedPoint2D.java @@ -0,0 +1,556 @@ +/* + * $Id$ + * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc + * + * Copyright (c) 2000-2012 Stephane GALLAND. + * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, + * Universite de Technologie de Belfort-Montbeliard. + * Copyright (c) 2013-2016 The original authors, and other authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.arakhne.afc.math.geometry.d2; + +import org.eclipse.xtext.xbase.lib.Pure; + +import org.arakhne.afc.math.geometry.coordinatesystem.CoordinateSystem2D; +import org.arakhne.afc.vmutil.asserts.AssertMessages; + +/** A point 2D with two orientation vectors relative to the polyline: the direction and the normal to the point. + * + *
The orientation vectors have no physical existence, i.e. they exist only to represent the direction of the
+ * point and its normal when the point is part of a polyline. The normal vector is always perpendicular to the
+ * direction vector. The point stores its length on the polyline to avoid rounding errors at discretization.
+ *
+ * @param is the type of the points.
+ * @param The rotation is done according to the trigonometric coordinate.
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @see #turn(double, OrientedPoint2D, OrientedPoint2D)
+ * @see #turnLeft(double)
+ * @see #turnRight(double)
+ */
+ default void turn(double angle) {
+ turn(angle, this);
+ }
+
+ /** Turn the given point about the given rotation angle around the origin point, and set this
+ * point with the result.
+ *
+ * The rotation is done according to the trigonometric coordinate.
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @param pointToTurn the point to turn.
+ * @see #turn(double, OrientedPoint2D, OrientedPoint2D)
+ * @see #turn(double)
+ * @see #turnLeft(double)
+ * @see #turnRight(double)
+ */
+ default void turn(double angle, OrientedPoint2D, ?, ?, ?, ?, ?> pointToTurn) {
+ assert pointToTurn != null : AssertMessages.notNullParameter(1);
+ final double sin = Math.sin(angle);
+ final double cos = Math.cos(angle);
+ final double x = cos * pointToTurn.getX() - sin * pointToTurn.getY();
+ final double y = sin * pointToTurn.getX() + cos * pointToTurn.getY();
+ set(x, y);
+ }
+
+ /** Turn the given point about the given rotation angle around the origin point, and set this
+ * point with the result.
+ *
+ * The rotation is done according to the trigonometric coordinate.
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @param pointToTurn the point to turn.
+ * @param origin the origin point.
+ * @see #turn(double, OrientedPoint2D)
+ * @see #turn(double)
+ * @see #turnLeft(double)
+ * @see #turnRight(double)
+ */
+ default void turn(double angle, OrientedPoint2D, ?, ?, ?, ?, ?> pointToTurn, OrientedPoint2D, ?, ?, ?, ?, ?> origin) {
+ assert pointToTurn != null : AssertMessages.notNullParameter(1);
+ assert origin != null : AssertMessages.notNullParameter(2);
+ final double sin = Math.sin(angle);
+ final double cos = Math.cos(angle);
+ final double vx = pointToTurn.getX() - origin.getX();
+ final double vy = pointToTurn.getY() - origin.getY();
+ final double x = cos * vx - sin * vy;
+ final double y = sin * vx + cos * vy;
+ set(x + origin.getX(), y + origin.getY());
+ }
+
+ /** Turn this vector on the left around the origin when the given rotation angle is positive.
+ *
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @see CoordinateSystem2D
+ * @see #turnLeft(double, OrientedPoint2D, OrientedPoint2D)
+ * @see #turn(double)
+ * @see #turnRight(double)
+ */
+ default void turnLeft(double angle) {
+ turnLeft(angle, this);
+ }
+
+ /** Turn the given vector on the left, and set this
+ * vector with the result.
+ *
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @param pointToTurn the vector to turn.
+ * @see CoordinateSystem2D
+ * @see #turnLeft(double, OrientedPoint2D, OrientedPoint2D)
+ * @see #turn(double)
+ * @see #turnRight(double)
+ */
+ default void turnLeft(double angle, OrientedPoint2D, ?, ?, ?, ?, ?> pointToTurn) {
+ assert pointToTurn != null : AssertMessages.notNullParameter(1);
+ final double sin = Math.sin(angle);
+ final double cos = Math.cos(angle);
+ final double x;
+ final double y;
+ if (CoordinateSystem2D.getDefaultCoordinateSystem().isRightHanded()) {
+ x = cos * pointToTurn.getX() - sin * pointToTurn.getY();
+ y = sin * pointToTurn.getX() + cos * pointToTurn.getY();
+ } else {
+ x = cos * pointToTurn.getX() + sin * pointToTurn.getY();
+ y = -sin * pointToTurn.getX() + cos * pointToTurn.getY();
+ }
+ set(x, y);
+ }
+
+ /** Turn the given vector on the left, and set this
+ * vector with the result.
+ *
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @param pointToTurn the vector to turn.
+ * @param origin the origin point.
+ * @see CoordinateSystem2D
+ * @see #turnLeft(double, OrientedPoint2D)
+ * @see #turn(double)
+ * @see #turnRight(double)
+ */
+ default void turnLeft(double angle, OrientedPoint2D, ?, ?, ?, ?, ?> pointToTurn, OrientedPoint2D, ?, ?, ?, ?, ?> origin) {
+ assert pointToTurn != null : AssertMessages.notNullParameter(1);
+ assert origin != null : AssertMessages.notNullParameter(2);
+ final double sin = Math.sin(angle);
+ final double cos = Math.cos(angle);
+ final double vx = pointToTurn.getX() - origin.getX();
+ final double vy = pointToTurn.getY() - origin.getY();
+ final double x;
+ final double y;
+ if (CoordinateSystem2D.getDefaultCoordinateSystem().isRightHanded()) {
+ x = cos * vx - sin * vy;
+ y = sin * vx + cos * vy;
+ } else {
+ x = cos * vx + sin * vy;
+ y = -sin * vx + cos * vy;
+ }
+ set(x + origin.getX(), y + origin.getY());
+ }
+
+ /** Turn this vector on the right around the origin when the given rotation angle is positive.
+ *
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @see CoordinateSystem2D
+ * @see #turn(double)
+ * @see #turnLeft(double)
+ */
+ default void turnRight(double angle) {
+ turnLeft(-angle, this);
+ }
+
+ /** Turn this vector on the right around the origin when the given rotation angle is positive.
+ *
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @param pointToTurn the vector to turn.
+ * @see CoordinateSystem2D
+ * @see #turn(double)
+ * @see #turnLeft(double)
+ */
+ default void turnRight(double angle, OrientedPoint2D, ?, ?, ?, ?, ?> pointToTurn) {
+ turnLeft(-angle, pointToTurn);
+ }
+
+ /** Turn this vector on the right around the origin when the given rotation angle is positive.
+ *
+ * A positive rotation angle corresponds to a left or right rotation
+ * according to the current {@link CoordinateSystem2D}.
+ *
+ * @param angle is the rotation angle in radians.
+ * @param pointToTurn the vector to turn.
+ * @param origin the origin point.
+ * @see CoordinateSystem2D
+ * @see #turn(double)
+ * @see #turnLeft(double)
+ */
+ default void turnRight(double angle, OrientedPoint2D, ?, ?, ?, ?, ?> pointToTurn,
+ OrientedPoint2D, ?, ?, ?, ?, ?> origin) {
+ turnLeft(-angle, pointToTurn, origin);
+ }
+
+}
diff --git a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/afp/GeomFactory2afp.java b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/afp/GeomFactory2afp.java
index 4f70247a4..3621ee3e3 100644
--- a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/afp/GeomFactory2afp.java
+++ b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/afp/GeomFactory2afp.java
@@ -176,6 +176,15 @@ E newArcPathElement(double startX, double startY, double targetX, double targetY
*/
OrientedPoint2afp, ?, E, P, V, B> newOrientedPoint(double x, double y);
+ /** Create an oriented point.
+ *
+ * @param x the x coordinate of the point.
+ * @param y the y coordinate of the point.
+ * @param length the length of the point on the polyline.
+ * @return the new oriented point
+ */
+ OrientedPoint2afp, ?, E, P, V, B> newOrientedPoint(double x, double y, double length);
+
/** Create an oriented point.
*
* @param x the x coordinate of the point.
@@ -186,6 +195,17 @@ E newArcPathElement(double startX, double startY, double targetX, double targetY
*/
OrientedPoint2afp, ?, E, P, V, B> newOrientedPoint(double x, double y, double dirX, double dirY);
+ /** Create an oriented point.
+ *
+ * @param x the x coordinate of the point.
+ * @param y the y coordinate of the point.
+ * @param length the length of the point on the polyline.
+ * @param dirX the x coordinate of the direction vector.
+ * @param dirY the y coordinate of the direction vector.
+ * @return the new oriented point
+ */
+ OrientedPoint2afp, ?, E, P, V, B> newOrientedPoint(double x, double y, double length, double dirX, double dirY);
+
/** Replies the {@link PathIterator2afp} that is corresponding to the given element.
*
* If the given element is already a {@link PathIterator2afp}, returns {@code this}.
diff --git a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/afp/OrientedPoint2afp.java b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/afp/OrientedPoint2afp.java
index a50720134..dac090b0d 100644
--- a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/afp/OrientedPoint2afp.java
+++ b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/afp/OrientedPoint2afp.java
@@ -20,23 +20,18 @@
package org.arakhne.afc.math.geometry.d2.afp;
-import org.eclipse.xtext.xbase.lib.Pure;
-
import org.arakhne.afc.math.MathConstants;
import org.arakhne.afc.math.MathUtil;
import org.arakhne.afc.math.geometry.CrossingComputationType;
import org.arakhne.afc.math.geometry.PathWindingRule;
+import org.arakhne.afc.math.geometry.d2.OrientedPoint2D;
import org.arakhne.afc.math.geometry.d2.Point2D;
import org.arakhne.afc.math.geometry.d2.Shape2D;
import org.arakhne.afc.math.geometry.d2.Transform2D;
import org.arakhne.afc.math.geometry.d2.Vector2D;
import org.arakhne.afc.vmutil.asserts.AssertMessages;
-/** A point 2D with two orientation vectors relative to the polyline: the direction and the normal to the point.
- *
- * The orientation vectors have no physical existence, i.e. they exist only to represent the direction of the
- * point and its normal when the point is part of a polyline. The normal vector is always perpendicular to the
- * direction vector..
+/** Fonctional interface representing a 2D oriented point on a plane.
*
* @param If the given element is already a {@link PathIterator2ai}, returns {@code this}.
diff --git a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/ai/OrientedPointShape2ai.java b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/ai/OrientedPoint2ai.java
similarity index 52%
rename from core/math/src/main/java/org/arakhne/afc/math/geometry/d2/ai/OrientedPointShape2ai.java
rename to core/math/src/main/java/org/arakhne/afc/math/geometry/d2/ai/OrientedPoint2ai.java
index 88ab60ecd..31f0c1a59 100644
--- a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/ai/OrientedPointShape2ai.java
+++ b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/ai/OrientedPoint2ai.java
@@ -20,12 +20,14 @@
package org.arakhne.afc.math.geometry.d2.ai;
-import org.eclipse.xtext.xbase.lib.Pure;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
import org.arakhne.afc.math.MathConstants;
import org.arakhne.afc.math.MathUtil;
import org.arakhne.afc.math.geometry.CrossingComputationType;
import org.arakhne.afc.math.geometry.PathWindingRule;
+import org.arakhne.afc.math.geometry.d2.OrientedPoint2D;
import org.arakhne.afc.math.geometry.d2.Point2D;
import org.arakhne.afc.math.geometry.d2.Shape2D;
import org.arakhne.afc.math.geometry.d2.Transform2D;
@@ -50,78 +52,157 @@
* @mavenartifactid $ArtifactId$
*/
@SuppressWarnings("unused")
-public interface OrientedPointShape2ai<
+public interface OrientedPoint2ai<
ST extends Shape2ai, ?, IE, P, V, B>,
- IT extends OrientedPointShape2ai, ?, IE, P, V, B>,
+ IT extends OrientedPoint2ai, ?, IE, P, V, B>,
IE extends PathElement2ai,
P extends Point2D super P, ? super V>,
V extends Vector2D super V, ? super P>,
- B extends Rectangle2ai, ?, IE, P, V, B>> extends Shape2ai the type of the points.
+ * @param , V extends Vector2D super V, ? super P>>
+ implements Iterator {
+ private int index;
+
+ private OrientedPoint2ai, ?, ?, P, V, ?> point;
+
+ /**
+ * @param pt the oriented point to iterate on.
+ */
+ public OrientedPointPointIterator(OrientedPoint2ai, ?, ?, P, V, ?> pt) {
+ assert pt != null : AssertMessages.notNullParameter();
+ this.point = pt;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.index <= 2;
+ }
+
+ @Override
+ public P next() {
+ switch (this.index++) {
+ case 0:
+ return this.point.getGeomFactory().newPoint(this.point.ix(), this.point.iy());
+ case 1:
+ return this.point.getGeomFactory().newPoint(this.point.idx(), this.point.idy());
+ case 2:
+ return this.point.getGeomFactory().newPoint(this.point.inx(), this.point.iny());
+ default:
+ throw new NoSuchElementException();
+ }
+ }
+
+ }
+
+ @Override
+ default PathIterator2ai getPointIterator() {
+ return new OrientedPointPointIterator<>(this);
}
@Override
@@ -146,27 +227,6 @@ default boolean contains(Point2D, ?> pt) {
return getX() == pt.getX() && getY() == pt.getY();
}
- @Override
- default boolean equalsToShape(IT shape) {
- if (shape == null) {
- return false;
- }
- if (shape == this) {
- return true;
- }
- // We don't need to check normal because it depends of direction
- return getX() == shape.getX() && getY() == shape.getY()
- && getDirectionX() == shape.getDirectionX()
- && getDirectionY() == shape.getDirectionY();
- }
-
- /** Replies this point.
- * @return this point
- */
- default P getPoint() {
- return getGeomFactory().newPoint(getX(), getY());
- }
-
@Override
default P getClosestPointTo(Circle2ai, ?, ?, ?, ?, ?> circle) {
return getPoint();
@@ -177,11 +237,6 @@ default P getClosestPointTo(Path2ai, ?, ?, ?, ?, ?> path) {
return getPoint();
}
- @Override
- default P getClosestPointTo(Point2D, ?> point) {
- return getPoint();
- }
-
@Override
default P getClosestPointTo(Rectangle2ai, ?, ?, ?, ?, ?> rectangle) {
return getPoint();
@@ -198,44 +253,20 @@ default P getClosestPointTo(Shape2D, ?, ?, ?, ?, ?> shape) {
}
@Override
- default double getDistanceL1(Point2D, ?> pt) {
- assert pt != null : AssertMessages.notNullParameter();
- return Point2D.getDistanceL1PointPoint(getX(), getY(), pt.getX(), pt.getY());
- }
-
- @Override
- default double getDistanceLinf(Point2D, ?> pt) {
- assert pt != null : AssertMessages.notNullParameter();
- return Point2D.getDistanceLinfPointPoint(getX(), getY(), pt.getX(), pt.getY());
- }
-
- @Override
- default double getDistanceSquared(Point2D, ?> pt) {
- assert pt != null : AssertMessages.notNullParameter();
- return Point2D.getDistanceSquaredPointPoint(getX(), getY(), pt.getX(), pt.getY());
- }
-
- @Override
- default double getDistance(Point2D, ?> pt) {
- assert pt != null : AssertMessages.notNullParameter();
- return Point2D.getDistancePointPoint(getX(), getY(), pt.getX(), pt.getY());
- }
-
- @Override
- default P getFarthestPointTo(Point2D, ?> point) {
+ default P getClosestPointTo(MultiShape2ai, ?, ?, ?, ?, ?, ?> multishape) {
return getPoint();
}
@Override
default boolean intersects(Circle2ai, ?, ?, ?, ?, ?> circle) {
assert circle != null : AssertMessages.notNullParameter();
- return circle.contains(getX(), getY());
+ return circle.contains(ix(), iy());
}
@Override
default boolean intersects(MultiShape2ai, ?, ?, ?, ?, ?, ?> multishape) {
assert multishape != null : AssertMessages.notNullParameter();
- return multishape.contains(getX(), getY());
+ return multishape.contains(ix(), iy());
}
@Override
@@ -245,7 +276,7 @@ default boolean intersects(PathIterator2ai> iterator) {
final int crossings = Path2ai.computeCrossingsFromPoint(
0,
iterator,
- getX(), getY(),
+ ix(), iy(),
CrossingComputationType.SIMPLE_INTERSECTION_WHEN_NOT_POLYGON);
return crossings == MathConstants.SHAPE_INTERSECTS
|| (crossings & mask) != 0;
@@ -254,35 +285,22 @@ default boolean intersects(PathIterator2ai> iterator) {
@Override
default boolean intersects(Rectangle2ai, ?, ?, ?, ?, ?> rectangle) {
assert rectangle != null : AssertMessages.notNullParameter();
- return rectangle.contains(getX(), getY());
+ return rectangle.contains(ix(), iy());
}
@Override
default boolean intersects(Segment2ai, ?, ?, ?, ?, ?> segment) {
assert segment != null : AssertMessages.notNullParameter();
- return segment.contains(getX(), getY());
- }
-
- @Override
- default boolean isEmpty() {
- return false;
+ return segment.contains(ix(), iy());
}
- /** Change the point.
- *
- * @param x x coordinate of the point.
- * @param y y coordinate of the point.
- */
- // No default implementation to ensure atomic change
- void set(double x, double y);
-
@Override
default void toBoundingBox(B box) {
assert box != null : AssertMessages.notNullParameter();
- final int x1 = MathUtil.min(getX(), getDirectionX(), getNormalX());
- final int y1 = MathUtil.min(getY(), getDirectionY(), getNormalY());
- final int x2 = MathUtil.max(getX(), getDirectionX(), getNormalX());
- final int y2 = MathUtil.max(getY(), getDirectionY(), getNormalY());
+ final int x1 = MathUtil.min(ix(), idx(), inx());
+ final int y1 = MathUtil.min(iy(), idy(), iny());
+ final int x2 = MathUtil.max(ix(), idx(), inx());
+ final int y2 = MathUtil.max(iy(), idy(), iny());
box.setFromCorners(x1, y1, x2, y2);
}
@@ -294,15 +312,13 @@ default void toBoundingBox(B box) {
*/
default void transforn(Transform2D transform) {
assert transform != null : AssertMessages.notNullParameter();
- final Point2D, ?> p = new InnerComputationPoint2ai(getX(), getY());
+ final Point2D, ?> p = new InnerComputationPoint2ai(ix(), iy());
transform.transform(p);
- set(p.getX(), p.getY());
+ set(p.ix(), p.iy());
}
@Override
default void translate(int dx, int dy) {
- set(getX() + dx, getY() + dy);
- setDirectionX(getDirectionX() + dx);
- setDirectionY(getDirectionY() + dy);
+ set(ix() + dx, iy() + dy, idx() + dx, idy() + dy);
}
}
diff --git a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/d/GeomFactory2d.java b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/d/GeomFactory2d.java
index 968b24bcc..01288c94f 100644
--- a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/d/GeomFactory2d.java
+++ b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/d/GeomFactory2d.java
@@ -175,11 +175,21 @@ public OrientedPoint2d newOrientedPoint(double x, double y) {
return new OrientedPoint2d(x, y);
}
+ @Override
+ public OrientedPoint2d newOrientedPoint(double x, double y, double length) {
+ return new OrientedPoint2d(x, y, length);
+ }
+
@Override
public OrientedPoint2d newOrientedPoint(double x, double y, double dirX, double dirY) {
return new OrientedPoint2d(x, y, dirX, dirY);
}
+ @Override
+ public OrientedPoint2d newOrientedPoint(double x, double y, double length, double dirX, double dirY) {
+ return new OrientedPoint2d(x, y, length, dirX, dirY);
+ }
+
@Override
public MultiShape2d> newMultiShape() {
return new MultiShape2d<>();
diff --git a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/d/OrientedPoint2d.java b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/d/OrientedPoint2d.java
index 260fc0f7b..b4b8b4afc 100644
--- a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/d/OrientedPoint2d.java
+++ b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/d/OrientedPoint2d.java
@@ -27,8 +27,8 @@
import org.arakhne.afc.math.geometry.d2.Vector2D;
import org.arakhne.afc.math.geometry.d2.afp.OrientedPoint2afp;
-/**
- * TODO .
+/** 2D oriented point with double precision floating-point numbers.
+ *
* @author $Author: tpiotrow$
* @version $FullVersion$
* @mavengroupid $GroupId$
@@ -48,6 +48,8 @@ public class OrientedPoint2d
private double dy;
+ private double len;
+
/** Construct an empty oriented point.
*/
public OrientedPoint2d() {
@@ -61,6 +63,14 @@ public OrientedPoint2d(Point2D, ?> point) {
this(point.getX(), point.getY());
}
+ /** Construct an oriented point from a point and its length on a polyline.
+ * @param point the point.
+ * @param length the length.
+ */
+ public OrientedPoint2d(Point2D, ?> point, double length) {
+ this(point.getX(), point.getY(), length);
+ }
+
/** Construct an oriented point from the two given coordinates.
* @param x x coordinate of the point.
* @param y y coordinate of the point.
@@ -69,6 +79,15 @@ public OrientedPoint2d(double x, double y) {
set(x, y);
}
+ /** Construct an oriented point from the two given coordinates and the length of the point on a polyline.
+ * @param x x coordinate of the point.
+ * @param y y coordinate of the point.
+ * @param length the length
+ */
+ public OrientedPoint2d(double x, double y, double length) {
+ set(x, y, length);
+ }
+
/** Construct an oriented point from a point and a direction vector.
* @param point the point.
* @param vector the direction vector.
@@ -77,6 +96,15 @@ public OrientedPoint2d(Point2D, ?> point, Vector2D, ?> vector) {
this(point.getX(), point.getY(), vector.getX(), vector.getY());
}
+ /** Construct an oriented point from a point, its length, and a direction vector.
+ * @param point the point.
+ * @param length the length of the point
+ * @param vector the direction vector.
+ */
+ public OrientedPoint2d(Point2D, ?> point, double length, Vector2D, ?> vector) {
+ this(point.getX(), point.getY(), length, vector.getX(), vector.getY());
+ }
+
/** Construct an oriented point from the two given coordinates.
* @param x x coordinate of the point.
* @param y y coordinate of the point.
@@ -87,6 +115,17 @@ public OrientedPoint2d(double x, double y, double dirX, double dirY) {
set(x, y, dirX, dirY);
}
+ /** Construct an oriented point from the given coordinates.
+ * @param x x coordinate of the point.
+ * @param y y coordinate of the point.
+ * @param length the length of the point on the polyline.
+ * @param dirX x coordinate of the vector.
+ * @param dirY y coordinate of the vector.
+ */
+ public OrientedPoint2d(double x, double y, double length, double dirX, double dirY) {
+ set(x, y, length, dirX, dirY);
+ }
+
@Pure
@Override
public int hashCode() {
@@ -95,6 +134,7 @@ public int hashCode() {
bits = 31 * bits + Double.hashCode(this.py);
bits = 31 * bits + Double.hashCode(this.dx);
bits = 31 * bits + Double.hashCode(this.dy);
+ bits = 31 * bits + Double.hashCode(this.len);
final int b = (int) bits;
return b ^ (b >> 31);
}
@@ -108,6 +148,8 @@ public String toString() {
b.append(", "); //$NON-NLS-1$
b.append(getY());
b.append(")|("); //$NON-NLS-1$
+ b.append(getLength());
+ b.append(")|("); //$NON-NLS-1$
b.append(getDirectionX());
b.append(", "); //$NON-NLS-1$
b.append(getDirectionY());
@@ -133,6 +175,48 @@ public OrientedPoint2d createTransformedShape(Transform2D transform) {
return getGeomFactory().newOrientedPoint(x1, y1, point.getX(), point.getY());
}
+ @Override
+ public void set(int x, int y) {
+ if (this.px != x || this.py != y) {
+ this.px = x;
+ this.py = y;
+ fireGeometryChange();
+ }
+ }
+
+ @Override
+ public void set(int x, int y, int length) {
+ if (this.px != x || this.py != y || this.len != length) {
+ this.px = x;
+ this.py = y;
+ this.len = length;
+ fireGeometryChange();
+ }
+ }
+
+ @Override
+ public void set(int x, int y, int dirX, int dirY) {
+ if (this.px != x || this.py != y || this.dx != dirX || this.dy != dirY) {
+ this.px = x;
+ this.py = y;
+ this.dx = dirX;
+ this.dy = dirY;
+ fireGeometryChange();
+ }
+ }
+
+ @Override
+ public void set(int x, int y, int length, int dirX, int dirY) {
+ if (this.px != x || this.py != y || this.len != length || this.dx != dirX || this.dy != dirY) {
+ this.px = x;
+ this.py = y;
+ this.dx = dirX;
+ this.dy = dirY;
+ this.len = length;
+ fireGeometryChange();
+ }
+ }
+
@Override
public void set(double x, double y) {
if (this.px != x || this.py != y) {
@@ -142,6 +226,16 @@ public void set(double x, double y) {
}
}
+ @Override
+ public void set(double x, double y, double length) {
+ if (this.px != x || this.py != y || this.len != length) {
+ this.px = x;
+ this.py = y;
+ this.len = length;
+ fireGeometryChange();
+ }
+ }
+
@Override
public void set(double x, double y, double dirX, double dirY) {
if (this.px != x || this.py != y || this.dx != dirX || this.dy != dirY) {
@@ -153,6 +247,26 @@ public void set(double x, double y, double dirX, double dirY) {
}
}
+ @Override
+ public void set(double x, double y, double length, double dirX, double dirY) {
+ if (this.px != x || this.py != y || this.len != length || this.dx != dirX || this.dy != dirY) {
+ this.px = x;
+ this.py = y;
+ this.dx = dirX;
+ this.dy = dirY;
+ this.len = length;
+ fireGeometryChange();
+ }
+ }
+
+ @Override
+ public void setX(int x) {
+ if (this.px != x) {
+ this.px = x;
+ fireGeometryChange();
+ }
+ }
+
@Override
public void setX(double x) {
if (this.px != x) {
@@ -161,6 +275,14 @@ public void setX(double x) {
}
}
+ @Override
+ public void setY(int y) {
+ if (this.py != y) {
+ this.py = y;
+ fireGeometryChange();
+ }
+ }
+
@Override
public void setY(double y) {
if (this.py != y) {
@@ -169,6 +291,14 @@ public void setY(double y) {
}
}
+ @Override
+ public void setDirectionX(int dirX) {
+ if (this.dx != dirX) {
+ this.dx = dirX;
+ fireGeometryChange();
+ }
+ }
+
@Override
public void setDirectionX(double dirX) {
if (this.dx != dirX) {
@@ -177,6 +307,14 @@ public void setDirectionX(double dirX) {
}
}
+ @Override
+ public void setDirectionY(int dirY) {
+ if (this.dy != dirY) {
+ this.dy = dirY;
+ fireGeometryChange();
+ }
+ }
+
@Override
public void setDirectionY(double dirY) {
if (this.dy != dirY) {
@@ -185,23 +323,69 @@ public void setDirectionY(double dirY) {
}
}
+ @Override
+ public void setLength(int length) {
+ if (this.len != length) {
+ this.len = length;
+ fireGeometryChange();
+ }
+ }
+
+ @Override
+ public void setLength(double length) {
+ if (this.len != length) {
+ this.len = length;
+ fireGeometryChange();
+ }
+ }
+
@Override
public double getX() {
return this.px;
}
+ @Override
+ public int ix() {
+ return (int) Math.round(this.px);
+ }
+
@Override
public double getY() {
return this.py;
}
+ @Override
+ public int iy() {
+ return (int) Math.round(this.py);
+ }
+
@Override
public double getDirectionX() {
return this.dx;
}
+ @Override
+ public int idx() {
+ return (int) Math.round(this.dx);
+ }
+
@Override
public double getDirectionY() {
return this.dy;
}
+
+ @Override
+ public int idy() {
+ return (int) Math.round(this.dy);
+ }
+
+ @Override
+ public double getLength() {
+ return this.len;
+ }
+
+ @Override
+ public int ilen() {
+ return (int) Math.round(this.len);
+ }
}
diff --git a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/i/GeomFactory2i.java b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/i/GeomFactory2i.java
index 992cdd5bd..ebf9e5937 100644
--- a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/i/GeomFactory2i.java
+++ b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/i/GeomFactory2i.java
@@ -164,6 +164,26 @@ public Segment2i newSegment(int x1, int y1, int x2, int y2) {
return new Segment2i(x1, y1, x2, y2);
}
+ @Override
+ public OrientedPoint2i newOrientedPoint(int x, int y) {
+ return new OrientedPoint2i(x, y);
+ }
+
+ @Override
+ public OrientedPoint2i newOrientedPoint(int x, int y, int length) {
+ return new OrientedPoint2i(x, y, length);
+ }
+
+ @Override
+ public OrientedPoint2i newOrientedPoint(int x, int y, int dirX, int dirY) {
+ return new OrientedPoint2i(x, y, dirX, dirY);
+ }
+
+ @Override
+ public OrientedPoint2i newOrientedPoint(int x, int y, int length, int dirX, int dirY) {
+ return new OrientedPoint2i(x, y, length, dirX, dirY);
+ }
+
@Override
public MultiShape2i> newMultiShape() {
return new MultiShape2i<>();
diff --git a/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/i/OrientedPoint2i.java b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/i/OrientedPoint2i.java
new file mode 100644
index 000000000..63ecc2992
--- /dev/null
+++ b/core/math/src/main/java/org/arakhne/afc/math/geometry/d2/i/OrientedPoint2i.java
@@ -0,0 +1,391 @@
+/*
+ * $Id$
+ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc
+ *
+ * Copyright (c) 2000-2012 Stephane GALLAND.
+ * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports,
+ * Universite de Technologie de Belfort-Montbeliard.
+ * Copyright (c) 2013-2016 The original authors, and other authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.arakhne.afc.math.geometry.d2.i;
+
+import org.eclipse.xtext.xbase.lib.Pure;
+
+import org.arakhne.afc.math.geometry.d2.Point2D;
+import org.arakhne.afc.math.geometry.d2.Transform2D;
+import org.arakhne.afc.math.geometry.d2.Vector2D;
+import org.arakhne.afc.math.geometry.d2.ai.OrientedPoint2ai;
+
+/** 2D oriented point with int precision floating-point numbers.
+ *
+ * @author $Author: tpiotrow$
+ * @version $FullVersion$
+ * @mavengroupid $GroupId$
+ * @mavenartifactid $ArtifactId$
+ */
+public class OrientedPoint2i
+ extends AbstractShape2inull
.
+ */
+ public OrientedPointPathIterator(OrientedPoint2ai, ?, T, ?, ?, ?> point, Transform2D transform) {
+ assert point != null : AssertMessages.notNullParameter();
+ this.point = point;
+ this.transform = transform == null || transform.isIdentity() ? null : transform;
+ this.px = point.ix();
+ this.py = point.iy();
+ this.dx = point.idx();
+ this.dy = point.idy();
+ }
+
+ @Override
+ public PathWindingRule getWindingRule() {
+ return PathWindingRule.NON_ZERO;
+ }
+
+ @Override
+ public boolean isPolyline() {
+ return false;
+ }
+
+ @Override
+ public boolean isCurved() {
+ return false;
+ }
+
+ @Override
+ public boolean isMultiParts() {
+ return true;
+ }
+
+ @Override
+ public boolean isPolygon() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.index <= 2;
+ }
+
+ @Override
+ public T next() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public GeomFactory2ai