View Javadoc
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 &pi; and theta (in case of a Ray3d) subtracted from &pi;
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  }