Skip to content

Commit

Permalink
[math] Add "arcTo" to Path2D.
Browse files Browse the repository at this point in the history
see #38

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed May 20, 2016
1 parent 74513aa commit b18e918
Show file tree
Hide file tree
Showing 13 changed files with 1,211 additions and 23 deletions.
115 changes: 114 additions & 1 deletion core/math/src/main/java/org/arakhne/afc/math/geometry/d2/Path2D.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,106 @@ public interface Path2D<
*/
void curveTo(Point2D<?, ?> ctrl1, Point2D<?, ?> ctrl2, Point2D<?, ?> to);

/**
/**
* Adds a section of an shallow ellipse to the current path.
* The ellipse from which a quadrant is taken is the ellipse that would be
* inscribed in a parallelogram defined by 3 points,
* The current point which is considered to be the midpoint of the edge
* leading into the corner of the ellipse where the ellipse grazes it,
* {@code (ctrlx, ctrly)} which is considered to be the location of the
* corner of the parallelogram in which the ellipse is inscribed,
* and {@code (tox, toy)} which is considered to be the midpoint of the
* edge leading away from the corner of the oval where the oval grazes it.
*
* <p><img src="./doc-files/arcto0.png"/>
*
* <p>Only the portion of the ellipse from {@code tfrom} to {@code tto}
* will be included where {@code 0f} represents the point where the
* ellipse grazes the leading edge, {@code 1f} represents the point where
* the oval grazes the trailing edge, and {@code 0.5f} represents the
* point on the oval closest to the control point.
* The two values must satisfy the relation
* {@code (0 <= tfrom <= tto <= 1)}.
*
* <p>If {@code tfrom} is not {@code 0f} then the caller would most likely
* want to use one of the arc {@code type} values that inserts a segment
* leading to the initial point.
* An initial {@link #moveTo(double, double)} or {@link #lineTo(double, double)} can be added to direct
* the path to the starting point of the ellipse section if
* {@link ArcType#MOVE_THEN_ARC} or
* {@link ArcType#LINE_THEN_ARC} are
* specified by the type argument.
* The {@code lineTo} path segment will only be added if the current point
* is not already at the indicated location to avoid spurious empty line
* segments.
* The type can be specified as
* {@link ArcType.CORNER_ONLY} if the current point
* on the path is known to be at the starting point of the ellipse section.
*
* @param ctrl the control point, i.e. the corner of the parallelogram in which the ellipse is inscribed.
* @param to the target point.
* @param tfrom the fraction of the ellipse section where the curve should start.
* @param tto the fraction of the ellipse section where the curve should end
* @param type the specification of what additional path segments should
* be appended to lead the current path to the starting point.
*/
void arcTo(Point2D<?, ?> ctrl, Point2D<?, ?> to, double tfrom, double tto, ArcType type);

/**
* Adds a section of an shallow ellipse to the current path.
*
* <p>This function is equivalent to:<pre><code>
* this.arcTo(ctrl, to, 0.0, 1.0, ArcType.ARCONLY);
* </code></pre>
*
* @param ctrl the control point, i.e. the corner of the parallelogram in which the ellipse is inscribed.
* @param to the target point.
*/
default void arcTo(Point2D<?, ?> ctrl, Point2D<?, ?> to) {
arcTo(ctrl, to, 0., 1., ArcType.ARC_ONLY);
}

/**
* Adds a section of an shallow ellipse to the current path.
* The ellipse from which the portions are extracted follows the rules:
* <ul>
* <li>The ellipse will have its X axis tilted from horizontal by the
* angle {@code xAxisRotation} specified in radians.</li>
* <li>The ellipse will have the X and Y radii (viewed from its tilted
* coordinate system) specified by {@code radiusx} and {@code radiusy}
* unless that ellipse is too small to bridge the gap from the current
* point to the specified destination point in which case a larger
* ellipse with the same ratio of dimensions will be substituted instead.</li>
* <li>The ellipse may slide perpendicular to the direction from the
* current point to the specified destination point so that it just
* touches the two points.
* The direction it slides (to the "left" or to the "right") will be
* chosen to meet the criteria specified by the two boolean flags as
* described below.
* Only one direction will allow the method to meet both criteria.</li>
* <li>If the {@code largeArcFlag} is true, then the ellipse will sweep
* the longer way around the ellipse that meets these criteria.</li>
* <li>If the {@code sweepFlag} is true, then the ellipse will sweep
* clockwise around the ellipse that meets these criteria.</li>
* </ul>
*
* <p><img src="../doc-files/arcto1.png" />
*
* <p>The method will do nothing if the destination point is the same as
* the current point.
* The method will draw a simple line segment to the destination point
* if either of the two radii are zero.
*
* @param to the target point.
* @param radii the X and Y radii of the tilted ellipse.
* @param xAxisRotation the angle of tilt of the ellipse.
* @param largeArcFlag <code>true</code> iff the path will sweep the long way around the ellipse.
* @param sweepFlag <code>true</code> iff the path will sweep clockwise around the ellipse.
* @see "http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands"
*/
void arcTo(Point2D<?, ?> to, Vector2D<?, ?> radii, double xAxisRotation, boolean largeArcFlag, boolean sweepFlag);

/**
* Closes the current subpath by drawing a straight line back to
* the coordinates of the last {@code moveTo}. If the path is already
* closed or if the previous coordinates are for a {@code moveTo}
Expand Down Expand Up @@ -351,4 +450,18 @@ default double getLength() {
@Pure
boolean containsControlPoint(Point2D<?, ?> point);

/** Type of drawing to used when drawing an arc.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
* @since 13.0
*/
enum ArcType {
ARC_ONLY,
MOVE_THEN_ARC,
LINE_THEN_ARC
}

}

0 comments on commit b18e918

Please sign in to comment.