1 package org.djutils.draw.line;
2
3 import org.djutils.draw.Directed;
4 import org.djutils.draw.DrawRuntimeException;
5 import org.djutils.draw.point.Point;
6 import org.djutils.exceptions.Throw;
7
8 /**
9 * A Ray is a half-line; it has one end point with non-infinite coordinates; the other end point is infinitely far away.
10 * <p>
11 * Copyright (c) 2020-2022 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
12 * BSD-style license. See <a href="https://djutils.org/docs/current/djutils/licenses.html">DJUTILS License</a>.
13 * </p>
14 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
15 * @author <a href="https://www.tudelft.nl/pknoppers">Peter Knoppers</a>
16 * @param <R> The Ray type (2d or 3d)
17 * @param <P> The Point type (2d, or 3d)
18 */
19 public interface Ray<R extends Ray<R, P>, P extends Point<P>> extends Directed<R>, Project<P>
20 {
21 /**
22 * Get the finite end point of this Ray.
23 * @return P; the finite end point of this Ray
24 */
25 P getEndPoint();
26
27 /**
28 * Retrieve the angle from the positive X axis direction in radians.
29 * @return double; the angle from the positive X axis direction in radians
30 */
31 double getPhi();
32
33 /**
34 * Flip the direction of the Ray (creates and returns a new Ray instance).
35 * @return R; Ray at the same location, but with phi incremented by π and theta (in case of a Ray3d) subtracted from π
36 */
37 R flip();
38
39 /**
40 * Get the location at a position on the line, with its direction. Position must be a positive, finite value
41 * @param position double; the position on the line for which to calculate the point on the line
42 * @return R; a ray with the same direction as this ray (even if the direction of this ray is not normalized)
43 * @throws DrawRuntimeException when position less than 0.0, infinite, or NaN.
44 */
45 default R getLocation(double position) throws DrawRuntimeException
46 {
47 Throw.when(Double.isNaN(position) || position < 0, DrawRuntimeException.class, "position must be finite and positive");
48 return getLocationExtended(position);
49 }
50
51 /**
52 * Get the location at a position on the line, with its direction. Position must be a positive, finite value
53 * @param position double; the position on the line for which to calculate the point on the line
54 * @return R; a ray with the same direction as this ray
55 * @throws DrawRuntimeException when position infinite, or NaN.
56 */
57 R getLocationExtended(double position) throws DrawRuntimeException;
58
59 /**
60 * Project a Point on a Ray. If the the projected points lies outside the ray, the start point of the ray is returned.
61 * Otherwise the closest point on the ray is returned. <br>
62 * Adapted from <a href="http://paulbourke.net/geometry/pointlineplane/DistancePoint.java">example code provided by Paul
63 * Bourke</a>.
64 * @param point P; the point to project onto the segment
65 * @return P; either the start point, or the end point of the segment or a Point2d that lies somewhere in between those two.
66 * @throws NullPointerException when point is null
67 */
68 P closestPointOnRay(P point) throws NullPointerException;
69
70 }