averbraeck / opentrafficsim

Open Source Multi-Level Traffic Simulator
BSD 3-Clause "New" or "Revised" License
28 stars 8 forks source link

Geometry utility to deal with offsets, widths and lane connections #73

Closed WJSchakel closed 4 months ago

WJSchakel commented 1 year ago

The current geometry implementations have several issues:

To overcome these issues the following principles are designed:

  1. Geometry utils (one in ots-core and one in ots-road) will be the central places that define geometry logic.
  2. All CrossSectionElement will simply receive a design line and shape. No internal (and obscure logic) will change this.
  3. Nodes have a direction, that links and lanes need to obey.
  4. Node direction is not strict for the links and lanes; the first and last line segments may deviate in their direction within bounds. (E.g. a circle arc may divide a 90° corner in 90 segments, causing the first and last segments to deviate from the node direction by 1°.)
  5. Both design lines and edge lines need to start/stop on the line through the node, perpendicular to the node direction.
  6. These start and end points need to at their offset on the perpendicular line. Note that this may cause slight narrowing of the first or last line segment.
  7. Link design lines are somewhere within the width of a road cross section, although this is not strict.
  8. Offset at link level is used to connect lanes appropriately where links merge or diverge. (For macroscopic purposes, this offset may be ignored.)
  9. Offset of the entire cross-section on a link is used to connect successive links using road layouts with different locations of the link design line.
  10. Offset of individual lanes and lines is used if this changes over the length of the link.

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.

WJSchakel commented 1 year ago

Quite a lot of changes have been made in a first big iteration to tackle the above issues.

WJSchakel commented 1 year ago

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.

WJSchakel commented 1 year ago

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:

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: