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