ContinuousPolyLine.java
package org.opentrafficsim.core.geometry;
import java.util.List;
import org.djutils.draw.line.PolyLine2d;
import org.djutils.draw.line.Ray2d;
import org.djutils.draw.point.OrientedPoint2d;
import org.djutils.draw.point.Point2d;
import org.djutils.exceptions.Throw;
import org.djutils.exceptions.Try;
/**
* Continuous definition of a PolyLine. Naive approaches are applied for offsets, since polylines have no exact information for
* this.
* <p>
* Copyright (c) 2023-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
* BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
* </p>
* @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
*/
public class ContinuousPolyLine implements ContinuousLine
{
/** Line. */
private final PolyLine2d line;
/** Start point. */
private final OrientedPoint2d startPoint;
/** End points. */
private final OrientedPoint2d endPoint;
/**
* Define continuous line from polyline. Start and end point direction are derived from the line.
* @param line OtsLine2d; line.
*/
public ContinuousPolyLine(final PolyLine2d line)
{
Throw.whenNull(line, "Line may not be null.");
this.line = line;
Ray2d startRay = line.getLocationFractionExtended(0.0);
Ray2d endRay = line.getLocationFractionExtended(1.0);
this.startPoint = new OrientedPoint2d(startRay.x, startRay.y, startRay.phi);
this.endPoint = new OrientedPoint2d(endRay.x, endRay.y, endRay.phi);
}
/**
* Define continuous line from polyline. Start and end point are given and may alter the direction at the endpoints
* (slightly).
* @param line OtsLine2d; line.
* @param startPoint OrientedPoint2d; start point.
* @param endPoint OrientedPoint2d; end point.
*/
public ContinuousPolyLine(final PolyLine2d line, final OrientedPoint2d startPoint, final OrientedPoint2d endPoint)
{
Throw.whenNull(line, "Line may not be null.");
this.line = line;
this.startPoint = startPoint;
this.endPoint = endPoint;
}
/** {@inheritDoc} */
@Override
public OrientedPoint2d getStartPoint()
{
return this.startPoint;
}
/** {@inheritDoc} */
@Override
public OrientedPoint2d getEndPoint()
{
return this.endPoint;
}
/** {@inheritDoc} */
@Override
public double getStartCurvature()
{
return 1.0 / getStartRadius();
}
/** {@inheritDoc} */
@Override
public double getEndCurvature()
{
return 1.0 / getEndRadius();
}
/** {@inheritDoc} */
@Override
public double getStartRadius()
{
return Try.assign(() -> new OtsLine2d(this.line).getProjectedRadius(0.0).si, "0.0 should be in range.");
}
/** {@inheritDoc} */
@Override
public double getEndRadius()
{
return Try.assign(() -> new OtsLine2d(this.line).getProjectedRadius(1.0).si, "0.0 should be in range.");
}
/**
* Polyline from continuous line. Returns the line as is.
* @return PolyLine2d; polyline.
*/
public PolyLine2d flatten()
{
return this.line;
}
/**
* Returns the line as is. Flattener is ignored.
* @param flattener Flattener; flattener (ignored).
* @return PolyLine2d; flattened line.
*/
@Override
public PolyLine2d flatten(final Flattener flattener)
{
return this.line;
}
/**
* Returns an offset line. This is a regular offset line, with start and end points moved to be perpendicular to end point
* directions.
* @param offsets FractionalLengthData; offset data.
* @return PolyLine2d; flattened line.
*/
public PolyLine2d offset(final FractionalLengthData offsets)
{
Throw.whenNull(offsets, "Offsets may not be null.");
PolyLine2d offsetLine = Try.assign(
() -> OtsGeometryUtil.offsetLine(this.line, offsets.getFractionalLengthsAsArray(), offsets.getValuesAsArray()),
"Unexpected exception while creating offset line.");
Point2d start = OtsGeometryUtil.offsetPoint(this.startPoint, offsets.get(0.0));
Point2d end = OtsGeometryUtil.offsetPoint(this.endPoint, offsets.get(1.0));
List<Point2d> points = offsetLine.getPointList();
points.set(0, start);
points.set(points.size() - 1, end);
return new PolyLine2d(points);
}
/**
* Returns the regular offset. Flattener is ignored.
* @param offsets FractionalLengthData; offset data.
* @param flattener Flattener; flattener (ignored).
* @return PolyLine2d; flattened line.
*/
@Override
public PolyLine2d flattenOffset(final FractionalLengthData offsets, final Flattener flattener)
{
return offset(offsets);
}
/** {@inheritDoc} */
@Override
public double getLength()
{
return this.line.getLength();
}
/** {@inheritDoc} */
@Override
public String toString()
{
return "ContinuousPolyLine [startPoint=" + this.startPoint + ", endPoint=" + this.endPoint + "]";
}
}