View Javadoc
1   package org.djutils.draw.curve;
2   
3   import org.djutils.draw.function.ContinuousPiecewiseLinearFunction;
4   import org.djutils.draw.line.PolyLine2d;
5   import org.djutils.draw.line.Ray2d;
6   import org.djutils.draw.point.DirectedPoint2d;
7   import org.djutils.draw.point.Point2d;
8   import org.djutils.exceptions.Throw;
9   
10  /**
11   * Continuous curve implementation of a straight in 2d.
12   * <p>
13   * Copyright (c) 2023-2025 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
14   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
15   * </p>
16   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
18   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
19   */
20  public class Straight2d implements Curve2d, OffsetCurve2d
21  {
22  
23      /** Start point with direction. */
24      private final DirectedPoint2d startPoint;
25  
26      /** End point with direction. */
27      private final DirectedPoint2d endPoint;
28  
29      /** Length. */
30      private final double length;
31  
32      /**
33       * Constructor.
34       * @param startPoint start point.
35       * @param length length.
36       * @throws NullPointerException when <code>startPoint</code> is <code>null</code>
37       * @throws IllegalArgumentException when <code>length &le; 0.0</code>
38       */
39      public Straight2d(final DirectedPoint2d startPoint, final double length)
40      {
41          Throw.whenNull(startPoint, "startPoint");
42          Throw.when(length <= 0.0, IllegalArgumentException.class, "Length must be above 0.");
43          this.startPoint = startPoint;
44          this.endPoint = new Ray2d(startPoint).getLocation(length);
45          this.length = length;
46      }
47  
48      /**
49       * Start curvature of this Straight.
50       * @return start curvature of this Straight
51       */
52      public double getStartCurvature()
53      {
54          return 0.0;
55      }
56  
57      /**
58       * End curvature of this Straight.
59       * @return end curvature of this Straight
60       */
61      public double getEndCurvature()
62      {
63          return 0.0;
64      }
65  
66      /**
67       * Return the point at the given fraction and the given lateral offset.
68       * @param fraction fraction along this line
69       * @param offset lateral offset (to the left)
70       * @return the point at the given fraction and lateral offset
71       */
72      private Point2d getPoint(final double fraction, final double offset)
73      {
74          if (offset == 0.0)
75          {
76              return new Ray2d(this.startPoint).getLocation(fraction * this.length);
77          }
78          else
79          {
80              double cos = Math.cos(this.startPoint.dirZ);
81              double sin = Math.sin(this.startPoint.dirZ);
82              double x = this.startPoint.x - offset * sin + cos * fraction * this.length;
83              double y = this.startPoint.y + offset * cos + sin * fraction * this.length;
84              return new Point2d(x, y);
85          }
86      }
87  
88      @Override
89      public Point2d getPoint(final double fraction)
90      {
91          return getPoint(fraction, 0);
92      }
93  
94      @Override
95      public Point2d getPoint(final double fraction, final ContinuousPiecewiseLinearFunction of)
96      {
97          return getPoint(fraction, of.get(fraction));
98      }
99  
100     @Override
101     public PolyLine2d toPolyLine(final Flattener2d flattener)
102     {
103         return new PolyLine2d(new Point2d(this.startPoint.x, this.startPoint.y), new Point2d(this.endPoint.x, this.endPoint.y));
104     }
105 
106     /**
107      * Offset a PolyLine2d based on variable offset. A straight uses no segments, other than for varying offset.
108      * @param offsets offsets, should contain keys 0.0 and 1.0.
109      * @return offset <code>PolyLine2d</code>
110      */
111     public PolyLine2d offset(final ContinuousPiecewiseLinearFunction offsets)
112     {
113         double[] lengths = new double[offsets.size()];
114         double[] values = new double[offsets.size()];
115         int index = 0;
116         for (ContinuousPiecewiseLinearFunction.TupleSt tuple : offsets)
117         {
118             lengths[index] = tuple.s();
119             values[index] = tuple.t();
120             index++;
121         }
122         return toPolyLine(null).offsetLine(lengths, values, 0.0);
123     }
124 
125     @Override
126     public PolyLine2d toPolyLine(final OffsetFlattener2d flattener, final ContinuousPiecewiseLinearFunction offsets)
127     {
128         return offset(offsets);
129     }
130 
131     @Override
132     public double getLength()
133     {
134         return this.length;
135     }
136 
137     @Override
138     public String toString()
139     {
140         return "Straight [startPoint=" + this.startPoint + ", endPoint=" + this.endPoint + ", length=" + this.length + "]";
141     }
142 
143 }