Closed WJSchakel closed 4 months ago
Quite a lot of changes have been made in a first big iteration to tackle the above issues.
CrossSectionElement
, and its subclasses Lane
, Stripe
and Shoulder
, now gets an OtsLine3d
and OtsShape
as center line and contour. These are no longer determined internally.fixLateralOffset()
and fixTightInnerCurve()
have been removed.ContinuousLine
, and its subclasses ContinuousArc
, ContinuousBezierCubic
, ContinuousClothoid
, ContinuousStraight
and ContinuousPolyLine
have been added. These classes define a design line continuously, and can be used to return a flattened OtsLine3d
of itself, or an offset line. All these lines obey the start and end directions.Bezier
now has a method cubicControlPoints()
that returns 4 control points using the regular logic of a shape factor and whether to use weighted points. This is used in ContinuousBezierCubic
. Method Bn
has been made package-private for the same reason.Clothoid
to ContinuousClothoid
.Added class FractionalLengthData
which stores 1-dimensional data along the length of a curve. This class is used for variable offsets, and also delivered by LaneGeometryUtil
to deliver center/left/right offsets. The class can return interpolated values.
Methods offset
and flatten
with input 'number of segments' or 'max deviation and angle' have been removed from ContinuousLine
and all subclasses.
A new interface Flattener
has been introduced. It is input in two new methods in ContinuousLine
and all subclasses:
flatten(Flattener)
flattenOffset(FractionalLengthData, Flattener)
Subclasses of ContinuousLine
can implement these methods either using, or ignoring, the flattener. For example, ContinuousStraight
is flattened to just two points. ContinuousBezierCubic
implements the offset procedure of before, splitting the Bezier in C-shaped Bezier segments. These segments are then used to provide information to the flattener.
A Flattener
expects input in the form of a FlattableLine
. This has methods Point2d get(double fraction)
and double getDirection(double fraction)
, for use in the various flattening procedures. Each ContinuousLine
subclass that uses the flattener, must present itself (or an offset of itself) as a FlattableLine
. This occurs using light-weight anonymous classes that can find points and directions, accounting for a possible variable offset. In most cases this is straightforward, especially if the relevant information has been pre-calculated (e.g. for a Clothoid).
There are 4 standard implementations of Flattener
, defined as classes as they require specification of input:
Flattener.NumSegments
based on a number of segments.Flattener.MaxDeviation
based on a maximum spatial deviation. This implements the procedure in Bezier
in djutils.Flattener.MaxAngle
based on a maximum angle between the continuous line, and a resulting polyline segment.Flattener.MaxDeviationAndAngle
which combines the two above in a single procedure.
The current geometry implementations have several issues:
CrossSectionElement
forces the first and last line segment in the direction of the node. This is done with a point at 1/3rd along the way to the next shape point, or at most at a distance equal to the element width. This creates very inconsistent shapes between elements on one link.CrossSectionElement
cannot be specified with geometry directly.CrossSectionElement
offsets are used to fix what is in essence a shift of the link design line, purely because it is then desired to let a link design line start at the from node and end in the end node. This occurs especially at merges/diverges where link design lines that are e.g. on the right-hand side of a cross-section will not meet up otherwise. This can create complicated and strange situations, e.g. an arc link where all lanes shift from from negative to positive offset. Aa a result, none of the lanes is an arc, and the lane contours will not connect neatly to the previous or next link.To overcome these issues the following principles are designed:
CrossSectionElement
will simply receive a design line and shape. No internal (and obscure logic) will change this.Rule 4 allows that shapes can be true to their design, and no awkward and complicating additional segments are required at the start and end. Rules 5 and 6 make sure that lanes from connected links connect neatly. The bounds of angle deviation in rule 4 are such that when the first/last point is placed on the perpendicular line through the node, at the correct offset, a clean line still results. The angle deviation may not be such that the first point in the inside of the bend at the node is placed beyond the second point due to an offset, e.g. taper lanes.