Package org.opentrafficsim.core.geometry
Class OtsLine2d
java.lang.Object
org.opentrafficsim.core.geometry.OtsLine2d
- All Implemented Interfaces:
Serializable
,nl.tudelft.simulation.dsol.animation.Locatable
public class OtsLine2d
extends Object
implements nl.tudelft.simulation.dsol.animation.Locatable, Serializable
Line with underlying PolyLine2d, a cached length indexed line, a cached length, and a cached centroid (all calculated on
first use). This class supports fractional projection.
Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
BSD-style license. See OpenTrafficSim License.
- Author:
- Alexander Verbraeck, Peter Knoppers, Guus Tamminga, Wouter Schakel
- See Also:
-
Nested Class Summary
Modifier and TypeClassDescriptionstatic enum
Fallback method for when fractional projection fails as the point is beyond the line or from numerical limitations. -
Constructor Summary
ConstructorDescriptionConstruct a new OtsShape (closed shape) from a Path2D.Construct a new OtsLine2d from a List<OtsPoint3d>.OtsLine2d
(org.djutils.draw.line.PolyLine2d line2d) Creates a new OtsLine2d based on 2d information.OtsLine2d
(org.djutils.draw.point.Point2d... points) Construct a new OtsLine2d. -
Method Summary
Modifier and TypeMethodDescriptionstatic OtsLine2d
concatenate
(double toleranceSI, OtsLine2d... lines) Concatenate several OtsLine2d instances.static OtsLine2d
concatenate
(double toleranceSI, OtsLine2d line1, OtsLine2d line2) Concatenate two OtsLine2d instances.static OtsLine2d
concatenate
(OtsLine2d... lines) Concatenate several OtsLine2d instances.static OtsLine2d
createAndCleanOtsLine2d
(List<org.djutils.draw.point.Point2d> pointList) Create an OtsLine2d, while cleaning repeating successive points.static OtsLine2d
createAndCleanOtsLine2d
(org.djutils.draw.point.Point2d... points) Create an OtsLine2d, while cleaning repeating successive points.boolean
final OtsLine2d
extract
(double start, double end) Create a new OtsLine2d that covers a sub-section of this OtsLine2d.final OtsLine2d
extract
(org.djunits.value.vdouble.scalar.Length start, org.djunits.value.vdouble.scalar.Length end) Create a new OtsLine2d that covers a sub-section of this OtsLine2d.final OtsLine2d
extractFractional
(double start, double end) Construct a new OtsLine2d covering the indicated fraction of this OtsLine2d.final org.djutils.draw.point.Point2d
get
(int i) Return one point of this OtsLine2d.org.djutils.draw.bounds.Bounds2d
final org.djutils.draw.point.Point2d
Retrieve the centroid of this OtsLine2d.final org.djutils.draw.bounds.Bounds2d
Get the bounding rectangle of this OtsLine2d.final org.djutils.draw.point.Point2d
getFirst()
Return the first point of this OtsLine2d.final org.djutils.draw.point.Point2d
getLast()
Return the last point of this OtsLine2d.final org.djunits.value.vdouble.scalar.Length
Return the length of this OtsLine2d in meters.org.djutils.draw.line.PolyLine2d
Returns a 2d representation of this line.org.djutils.draw.point.Point2d
final org.djutils.draw.point.OrientedPoint2d
getLocation
(org.djunits.value.vdouble.scalar.Length position) Get the location at a position on the line, with its direction.final org.djutils.draw.point.OrientedPoint2d
getLocationExtended
(org.djunits.value.vdouble.scalar.Length position) Get the location at a position on the line, with its direction.final org.djutils.draw.point.OrientedPoint2d
getLocationExtendedSI
(double positionSI) Get the location at a position on the line, with its direction.final org.djutils.draw.point.OrientedPoint2d
getLocationFraction
(double fraction) Get the location at a fraction of the line, with its direction.final org.djutils.draw.point.OrientedPoint2d
getLocationFraction
(double fraction, double tolerance) Get the location at a fraction of the line, with its direction.final org.djutils.draw.point.OrientedPoint2d
getLocationFractionExtended
(double fraction) Get the location at a fraction of the line (or outside the line), with its direction.final org.djutils.draw.point.OrientedPoint2d
getLocationSI
(double positionSI) Get the location at a position on the line, with its direction.final org.djutils.draw.point.Point2d[]
Return an array of OtsPoint3d that represents this OtsLine2d.org.djunits.value.vdouble.scalar.Length
getProjectedRadius
(double fraction) Returns the projected directional radius of the line at a given fraction.org.djunits.value.vdouble.scalar.Length
getProjectedVertexRadius
(int index) Calculates the directional radius at a vertex.double
getVertexFraction
(int index) Returns the length fraction at the vertex.int
hashCode()
final OtsLine2d
noiseFilterRamerDouglasPeucker
(double epsilon, boolean useHorizontalDistance) Deprecated.final OtsLine2d
offsetLine
(double offset) Construct parallel line.final OtsLine2d
offsetLine
(double[] relativeFractions, double[] offsets) Create a line at linearly varying offset from this line.final OtsLine2d
offsetLine
(double offsetAtStart, double offsetAtEnd) Create a line at linearly varying offset from this line.final double
projectFractional
(org.djunits.value.vdouble.scalar.Direction start, org.djunits.value.vdouble.scalar.Direction end, double x, double y, OtsLine2d.FractionalFallback fallback) Returns the fractional projection of a point to a line.final double
projectOrthogonal
(double x, double y) Returns the fractional position along this line of the orthogonal projection of point (x, y) on this line.final OtsLine2d
reverse()
Construct a new OtsLine2d with all points of this OtsLine2d in reverse order.final int
size()
Return the number of points in this OtsLine2d.final String
toExcel()
Convert the 2D projection of this OtsLine2d to something that MS-Excel can plot.final String
toPlot()
Convert the 2D projection of this OtsLine2d to Peter's plot format.toString()
final OtsLine2d
truncate
(double lengthSI) Truncate a line at the given length (less than the length of the line, and larger than zero) and return a new line.Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface nl.tudelft.simulation.dsol.animation.Locatable
getDirZ, getZ
-
Constructor Details
-
OtsLine2d
public OtsLine2d(org.djutils.draw.point.Point2d... points) Construct a new OtsLine2d.- Parameters:
points
- Point2d...; the array of points to construct this OtsLine2d from.
-
OtsLine2d
public OtsLine2d(org.djutils.draw.line.PolyLine2d line2d) Creates a new OtsLine2d based on 2d information. Elevation will be 0.- Parameters:
line2d
- PolyLine2d; 2d information.
-
OtsLine2d
Construct a new OtsLine2d from a List<OtsPoint3d>.- Parameters:
pointList
- List<OtsPoint3d>; the list of points to construct this OtsLine2d from.- Throws:
OtsGeometryException
- when the provided points do not constitute a valid line (too few points or identical adjacent points)
-
OtsLine2d
Construct a new OtsShape (closed shape) from a Path2D. Elevation will be 0.- Parameters:
path
- Path2D; the Path2D to construct this OtsLine2d from.- Throws:
OtsGeometryException
- when the provided points do not constitute a valid line (too few points or identical adjacent points)
-
-
Method Details
-
offsetLine
Construct parallel line.- Parameters:
offset
- double; offset distance from the reference line; positive is LEFT, negative is RIGHT- Returns:
- OtsLine2d; the line that has the specified offset from the reference line
-
noiseFilterRamerDouglasPeucker
@Deprecated public final OtsLine2d noiseFilterRamerDouglasPeucker(double epsilon, boolean useHorizontalDistance) Deprecated.Clean up a list of points that describe a polyLine by removing points that lie within epsilon distance of a more straightened version of the line.- Parameters:
epsilon
- double; maximal deviationuseHorizontalDistance
- boolean; if true; the horizontal distance is used; if false; the 3D distance is used- Returns:
- OtsLine2d; a new OtsLine2d containing all the remaining points
-
getLine2d
public org.djutils.draw.line.PolyLine2d getLine2d()Returns a 2d representation of this line.- Returns:
- PolyLine2d; Returns a 2d representation of this line.
-
offsetLine
Create a line at linearly varying offset from this line. The offset may change linearly from its initial value at the start of the reference line to its final offset value at the end of the reference line.- Parameters:
offsetAtStart
- double; offset at the start of the reference line (positive value is Left, negative value is Right)offsetAtEnd
- double; offset at the end of the reference line (positive value is Left, negative value is Right)- Returns:
- OtsLine2d; the OtsLine2d of the line at linearly changing offset of the reference line
-
offsetLine
public final OtsLine2d offsetLine(double[] relativeFractions, double[] offsets) throws OtsGeometryException Create a line at linearly varying offset from this line. The offset may change linearly from its initial value at the start of the reference line via a number of intermediate offsets at intermediate positions to its final offset value at the end of the reference line.- Parameters:
relativeFractions
- double[]; positional fractions for which the offsets have to be generatedoffsets
- double[]; offsets at the relative positions (positive value is Left, negative value is Right)- Returns:
- Geometry; the Geometry of the line at linearly changing offset of the reference line
- Throws:
OtsGeometryException
- when this method fails to create the offset line
-
concatenate
Concatenate several OtsLine2d instances.- Parameters:
lines
- OtsLine2d...; OtsLine2d... one or more OtsLine2d. The last point of the first <strong>must</strong> match the first of the second, etc.- Returns:
- OtsLine2d
-
concatenate
Concatenate two OtsLine2d instances. This method is separate for efficiency reasons.- Parameters:
toleranceSI
- double; the tolerance between the end point of a line and the first point of the next lineline1
- OtsLine2d; first lineline2
- OtsLine2d; second line- Returns:
- OtsLine2d
-
concatenate
Concatenate several OtsLine2d instances.- Parameters:
toleranceSI
- double; the tolerance between the end point of a line and the first point of the next linelines
- OtsLine2d...; OtsLine2d... one or more OtsLine2d. The last point of the first <strong>must</strong> match the first of the second, etc.- Returns:
- OtsLine2d
-
reverse
Construct a new OtsLine2d with all points of this OtsLine2d in reverse order.- Returns:
- OtsLine2d; the new OtsLine2d
-
extractFractional
Construct a new OtsLine2d covering the indicated fraction of this OtsLine2d.- Parameters:
start
- double; starting point, valid range [0..end)end
- double; ending point, valid range (start..1]- Returns:
- OtsLine2d; the new OtsLine2d
-
extract
public final OtsLine2d extract(org.djunits.value.vdouble.scalar.Length start, org.djunits.value.vdouble.scalar.Length end) Create a new OtsLine2d that covers a sub-section of this OtsLine2d.- Parameters:
start
- Length; the length along this OtsLine2d where the sub-section starts, valid range [0..end)end
- Length; length along this OtsLine2d where the sub-section ends, valid range (start..length (length is the length of this OtsLine2d)- Returns:
- OtsLine2d; the selected sub-section
-
extract
Create a new OtsLine2d that covers a sub-section of this OtsLine2d.- Parameters:
start
- double; length along this OtsLine2d where the sub-section starts, valid range [0..end)end
- double; length along this OtsLine2d where the sub-section ends, valid range (start..length (length is the length of this OtsLine2d)- Returns:
- OtsLine2d; the selected sub-section
-
createAndCleanOtsLine2d
public static OtsLine2d createAndCleanOtsLine2d(org.djutils.draw.point.Point2d... points) throws OtsGeometryException Create an OtsLine2d, while cleaning repeating successive points.- Parameters:
points
- Point2d...; the coordinates of the line as OtsPoint3d- Returns:
- the line
- Throws:
OtsGeometryException
- when number of points < 2
-
createAndCleanOtsLine2d
public static OtsLine2d createAndCleanOtsLine2d(List<org.djutils.draw.point.Point2d> pointList) throws OtsGeometryException Create an OtsLine2d, while cleaning repeating successive points.- Parameters:
pointList
- List<Point2d>; list of the coordinates of the line as OtsPoint3d; any duplicate points in this list are removed (this method may modify the provided list)- Returns:
- OtsLine2d; the line
- Throws:
OtsGeometryException
- when number of non-equal points < 2
-
size
public final int size()Return the number of points in this OtsLine2d. This is the number of points in horizontal plane.- Returns:
- the number of points on the line
-
getFirst
public final org.djutils.draw.point.Point2d getFirst()Return the first point of this OtsLine2d.- Returns:
- the first point on the line
-
getLast
public final org.djutils.draw.point.Point2d getLast()Return the last point of this OtsLine2d.- Returns:
- the last point on the line
-
get
Return one point of this OtsLine2d.- Parameters:
i
- int; the index of the point to retrieve- Returns:
- Point2d; the i-th point of the line
- Throws:
OtsGeometryException
- when i < 0 or i > the number of points
-
getLength
public final org.djunits.value.vdouble.scalar.Length getLength()Return the length of this OtsLine2d in meters. (Assuming that the coordinates of the points constituting this line are expressed in meters.)- Returns:
- the length of the line
-
getPoints
public final org.djutils.draw.point.Point2d[] getPoints()Return an array of OtsPoint3d that represents this OtsLine2d.- Returns:
- the points of this line
-
getLocationExtended
public final org.djutils.draw.point.OrientedPoint2d getLocationExtended(org.djunits.value.vdouble.scalar.Length position) Get the location at a position on the line, with its direction. Position can be below 0 or more than the line length. In that case, the position will be extrapolated in the direction of the line at its start or end.- Parameters:
position
- Length; the position on the line for which to calculate the point on, before, of after the line- Returns:
- a directed point
-
getLocationExtendedSI
public final org.djutils.draw.point.OrientedPoint2d getLocationExtendedSI(double positionSI) Get the location at a position on the line, with its direction. Position can be below 0 or more than the line length. In that case, the position will be extrapolated in the direction of the line at its start or end.- Parameters:
positionSI
- double; the position on the line for which to calculate the point on, before, of after the line, in SI units- Returns:
- a directed point
-
getLocationFraction
public final org.djutils.draw.point.OrientedPoint2d getLocationFraction(double fraction) throws OtsGeometryException Get the location at a fraction of the line, with its direction. Fraction should be between 0.0 and 1.0.- Parameters:
fraction
- double; the fraction for which to calculate the point on the line- Returns:
- a directed point
- Throws:
OtsGeometryException
- when fraction less than 0.0 or more than 1.0.
-
getLocationFraction
public final org.djutils.draw.point.OrientedPoint2d getLocationFraction(double fraction, double tolerance) throws OtsGeometryException Get the location at a fraction of the line, with its direction. Fraction should be between 0.0 and 1.0.- Parameters:
fraction
- double; the fraction for which to calculate the point on the linetolerance
- double; the delta from 0.0 and 1.0 that will be forgiven- Returns:
- a directed point
- Throws:
OtsGeometryException
- when fraction less than 0.0 or more than 1.0.
-
getLocationFractionExtended
public final org.djutils.draw.point.OrientedPoint2d getLocationFractionExtended(double fraction) Get the location at a fraction of the line (or outside the line), with its direction.- Parameters:
fraction
- double; the fraction for which to calculate the point on the line- Returns:
- a directed point
-
getLocation
public final org.djutils.draw.point.OrientedPoint2d getLocation(org.djunits.value.vdouble.scalar.Length position) throws OtsGeometryException Get the location at a position on the line, with its direction. Position should be between 0.0 and line length.- Parameters:
position
- Length; the position on the line for which to calculate the point on the line- Returns:
- a directed point
- Throws:
OtsGeometryException
- when position less than 0.0 or more than line length.
-
getLocationSI
public final org.djutils.draw.point.OrientedPoint2d getLocationSI(double positionSI) throws OtsGeometryException Get the location at a position on the line, with its direction. Position should be between 0.0 and line length.- Parameters:
positionSI
- double; the position on the line for which to calculate the point on the line- Returns:
- a directed point
- Throws:
OtsGeometryException
- when position less than 0.0 or more than line length.
-
truncate
Truncate a line at the given length (less than the length of the line, and larger than zero) and return a new line.- Parameters:
lengthSI
- double; the location where to truncate the line- Returns:
- a new OtsLine2d truncated at the exact position where line.getLength() == lengthSI
- Throws:
OtsGeometryException
- when position less than 0.0 or more than line length.
-
projectOrthogonal
public final double projectOrthogonal(double x, double y) Returns the fractional position along this line of the orthogonal projection of point (x, y) on this line. If the point is not orthogonal to the closest line segment, the nearest point is selected.- Parameters:
x
- double; x-coordinate of point to projecty
- double; y-coordinate of point to project- Returns:
- fractional position along this line of the orthogonal projection on this line of a point
-
projectFractional
public final double projectFractional(org.djunits.value.vdouble.scalar.Direction start, org.djunits.value.vdouble.scalar.Direction end, double x, double y, OtsLine2d.FractionalFallback fallback) Returns the fractional projection of a point to a line. The projection works by taking slices in space per line segment as shown below. A point is always projected to the nearest segment, but not necessarily to the closest point on that segment. The slices in space are analogous to a Voronoi diagram, but for the line segments instead of points. If fractional projection fails, the orthogonal projection is returned.
The point 'A' is projected to point 'B' on the 3rd segment of line 'C-D'. The line from 'A' to 'B' extends towards point 'E', which is the intersection of lines 'E-F' and 'E-G'. Line 'E-F' cuts the first bend of the 3rd segment (at point 'H') in half, while the line 'E-G' cuts the second bend of the 3rd segment (at point 'I') in half.____________________________ G . . | | . . . | . . . . helper lines | . . . | _.._.._ projection line | I. . . |____________________________| _.'._ . L F. _.' . '-. . .. B _.' . '-. . . _.\ . . D . . _.' : . . J . . _.' \ . . .. . _.' : . M . . ..-' \ . . . /H. A . . . / . . C _________/ . . . . . . K . . . . . . . . . . . . N . . . . . . . . . . . . . . . . . .E . . . . . .
Fractional projection may fail in three cases.- Numerical difficulties at slight bend, orthogonal projection returns the correct point.
- Fractional projection is possible only to segments that aren't the nearest segment(s).
- Fractional projection is possible for no segment.
orthoFallback = true
, orNaN
iforthoFallback = false
.- Parameters:
start
- Direction; direction in first pointend
- Direction; direction in last pointx
- double; x-coordinate of point to projecty
- double; y-coordinate of point to projectfallback
- FractionalFallback; fallback method for when fractional projection fails- Returns:
- fractional position along this line of the fractional projection on that line of a point
-
getProjectedRadius
public org.djunits.value.vdouble.scalar.Length getProjectedRadius(double fraction) throws OtsGeometryException Returns the projected directional radius of the line at a given fraction. Negative values reflect right-hand curvature in the design-line direction. The radius is taken as the minimum of the radii at the vertices before and after the given fraction. The radius at a vertex is calculated as the radius of a circle that is equidistant from both edges connected to the vertex. The circle center is on a line perpendicular to the shortest edge, crossing through the middle of the shortest edge. This method ignores Z components.- Parameters:
fraction
- double; fraction along the line, between 0.0 and 1.0 (both inclusive)- Returns:
- Length; radius; the local radius; or si field set to Double.NaN if line is totally straight
- Throws:
OtsGeometryException
- fraction out of bounds
-
getProjectedVertexRadius
public org.djunits.value.vdouble.scalar.Length getProjectedVertexRadius(int index) throws OtsGeometryException Calculates the directional radius at a vertex. Negative values reflect right-hand curvature in the design-line direction. The radius at a vertex is calculated as the radius of a circle that is equidistant from both edges connected to the vertex. The circle center is on a line perpendicular to the shortest edge, crossing through the middle of the shortest edge. This function ignores Z components.- Parameters:
index
- int; index of the vertex in range [1 ... size() - 2]- Returns:
- Length; radius at the vertex
- Throws:
OtsGeometryException
- if the index is out of bounds
-
getVertexFraction
Returns the length fraction at the vertex.- Parameters:
index
- int; index of vertex [0 ... size() - 1]- Returns:
- double; length fraction at the vertex
- Throws:
OtsGeometryException
- if the index is out of bounds
-
getCentroid
public final org.djutils.draw.point.Point2d getCentroid()Retrieve the centroid of this OtsLine2d.- Returns:
- OtsPoint3d; the centroid of this OtsLine2d
-
getEnvelope
public final org.djutils.draw.bounds.Bounds2d getEnvelope()Get the bounding rectangle of this OtsLine2d.- Returns:
- Rectangle2D; the bounding rectangle of this OtsLine2d
-
getLocation
public org.djutils.draw.point.Point2d getLocation()- Specified by:
getLocation
in interfacenl.tudelft.simulation.dsol.animation.Locatable
-
getBounds
public org.djutils.draw.bounds.Bounds2d getBounds()- Specified by:
getBounds
in interfacenl.tudelft.simulation.dsol.animation.Locatable
-
toString
-
hashCode
public int hashCode() -
equals
-
toExcel
Convert the 2D projection of this OtsLine2d to something that MS-Excel can plot.- Returns:
- excel XY plottable output
-
toPlot
Convert the 2D projection of this OtsLine2d to Peter's plot format.- Returns:
- Peter's format plot output
-