ContinuousPolyLine.java

  1. package org.opentrafficsim.core.geometry;

  2. import java.util.List;

  3. import org.djutils.draw.line.PolyLine2d;
  4. import org.djutils.draw.line.Ray2d;
  5. import org.djutils.draw.point.OrientedPoint2d;
  6. import org.djutils.draw.point.Point2d;
  7. import org.djutils.exceptions.Throw;
  8. import org.opentrafficsim.base.geometry.OtsGeometryUtil;
  9. import org.opentrafficsim.base.geometry.OtsLine2d;

  10. /**
  11.  * Continuous definition of a PolyLine. Naive approaches are applied for offsets, since polylines have no exact information for
  12.  * this.
  13.  * <p>
  14.  * Copyright (c) 2023-2024 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/wjschakel">Wouter Schakel</a>
  18.  */
  19. public class ContinuousPolyLine implements ContinuousLine
  20. {

  21.     /** Line. */
  22.     private final PolyLine2d line;

  23.     /** Start point. */
  24.     private final OrientedPoint2d startPoint;

  25.     /** End points. */
  26.     private final OrientedPoint2d endPoint;

  27.     /**
  28.      * Define continuous line from polyline. Start and end point direction are derived from the line.
  29.      * @param line line.
  30.      */
  31.     public ContinuousPolyLine(final PolyLine2d line)
  32.     {
  33.         Throw.whenNull(line, "Line may not be null.");
  34.         this.line = line;
  35.         Ray2d startRay = line.getLocationFractionExtended(0.0);
  36.         Ray2d endRay = line.getLocationFractionExtended(1.0);
  37.         this.startPoint = new OrientedPoint2d(startRay.x, startRay.y, startRay.phi);
  38.         this.endPoint = new OrientedPoint2d(endRay.x, endRay.y, endRay.phi);
  39.     }

  40.     /**
  41.      * Define continuous line from polyline. Start and end point are given and may alter the direction at the endpoints
  42.      * (slightly).
  43.      * @param line line.
  44.      * @param startPoint start point.
  45.      * @param endPoint end point.
  46.      */
  47.     public ContinuousPolyLine(final PolyLine2d line, final OrientedPoint2d startPoint, final OrientedPoint2d endPoint)
  48.     {
  49.         Throw.whenNull(line, "Line may not be null.");
  50.         this.line = line;
  51.         this.startPoint = startPoint;
  52.         this.endPoint = endPoint;
  53.     }

  54.     @Override
  55.     public OrientedPoint2d getStartPoint()
  56.     {
  57.         return this.startPoint;
  58.     }

  59.     @Override
  60.     public OrientedPoint2d getEndPoint()
  61.     {
  62.         return this.endPoint;
  63.     }

  64.     @Override
  65.     public double getStartCurvature()
  66.     {
  67.         return 1.0 / getStartRadius();
  68.     }

  69.     @Override
  70.     public double getEndCurvature()
  71.     {
  72.         return 1.0 / getEndRadius();
  73.     }

  74.     @Override
  75.     public double getStartRadius()
  76.     {
  77.         return new OtsLine2d(this.line).getProjectedRadius(0.0).si;
  78.     }

  79.     @Override
  80.     public double getEndRadius()
  81.     {
  82.         return new OtsLine2d(this.line).getProjectedRadius(1.0).si;
  83.     }

  84.     /**
  85.      * Polyline from continuous line. Returns the line as is.
  86.      * @return polyline.
  87.      */
  88.     public PolyLine2d flatten()
  89.     {
  90.         return this.line;
  91.     }

  92.     /**
  93.      * Returns the line as is. Flattener is ignored.
  94.      * @param flattener flattener (ignored).
  95.      * @return flattened line.
  96.      */
  97.     @Override
  98.     public PolyLine2d flatten(final Flattener flattener)
  99.     {
  100.         return this.line;
  101.     }

  102.     /**
  103.      * Returns an offset line. This is a regular offset line, with start and end points moved to be perpendicular to end point
  104.      * directions.
  105.      * @param offset offset data.
  106.      * @return flattened line.
  107.      */
  108.     public PolyLine2d offset(final ContinuousDoubleFunction offset)
  109.     {
  110.         Throw.whenNull(offset, "Offsets may not be null.");
  111.         double[] knots = offset.getKnots();
  112.         double[] knotOffset = new double[knots.length];
  113.         for (int i = 0; i < knots.length; i++)
  114.         {
  115.             knotOffset[i] = offset.apply(knots[i]);
  116.         }
  117.         PolyLine2d offsetLine =
  118.                 OtsGeometryUtil.offsetLine(this.line, knots, knotOffset);
  119.         Point2d start = OtsGeometryUtil.offsetPoint(this.startPoint, offset.apply(0.0));
  120.         Point2d end = OtsGeometryUtil.offsetPoint(this.endPoint, offset.apply(1.0));
  121.         List<Point2d> points = offsetLine.getPointList();
  122.         points.set(0, start);
  123.         points.set(points.size() - 1, end);
  124.         return new PolyLine2d(points);
  125.     }

  126.     /**
  127.      * Returns the regular offset. Flattener is ignored.
  128.      * @param offset offset data.
  129.      * @param flattener flattener (ignored).
  130.      * @return flattened line.
  131.      */
  132.     @Override
  133.     public PolyLine2d flattenOffset(final ContinuousDoubleFunction offset, final Flattener flattener)
  134.     {
  135.         return offset(offset);
  136.     }

  137.     @Override
  138.     public double getLength()
  139.     {
  140.         return this.line.getLength();
  141.     }

  142.     @Override
  143.     public String toString()
  144.     {
  145.         return "ContinuousPolyLine [startPoint=" + this.startPoint + ", endPoint=" + this.endPoint + "]";
  146.     }

  147. }