averbraeck / opentrafficsim

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

An unbounded naming chaos #100

Open WJSchakel opened 6 months ago

WJSchakel commented 6 months ago

Naming mess Take the following overview of methods I came across while working on issue #99. Many names are used interchangeably for similar concepts.

Type Class Method Remark
PolyLine2d LocatedObject .getGeometry() Must remain line (not polygon) e.g. for traffic lights and detectors.
List<Point2d> ConflictData .getContour()
Polygon2d SpatialObject .getShape()
Polygon2d DynamicSpatialObject .getShape(Time)
PolyLine2d TrafficLightDetectorData .getGeometry()
Bounds2d OtsLine2d .getEnvelope()
Bounds Locatable .getBounds()
OtsBounds2d OtsLocatable .getBounds()
Polygon2d Node .getShape() Never called.

What we need We have several names for what seems to be the same: geometry, envelope, contour, shape and bounds.

There are good arguments to distinguish three functionally different definitions:

  1. Geometry that defines where an object is in space, including its dimensionality (i.e. not just a point).
    • This can be used to check overlap between two non simple objects.
    • This is used to know where to animate objects.
  2. Geometry that defines the shape of an object, regardless of its position.
    • For moving objects this is a necessity to determine 1.
    • This allows formulations that are quicker to compute.
    • For example, is a point within a rectangle? By transforming the point to the coordinate system of the shape, this becomes a very simple abs(x)<dx and abs(y)<dy check.
    • Note that this is much more efficient than transforming some geometry regarding a location (going from 2 to 1), and then checking whether the point is within this generalized geometry.
    • Similarly, signed distance functions (negative values inside the object) can be computed quickly. See here. These functions are required for spatial calculations for example regarding visibility.
  3. Geometry that can be used quickly to filter many objects that are certainly not overlapping/not in need to animate/etc., wherever they may be.

What terms to use for which? Geometry: this is too broad of a term to specify what we mean. Envelope: this is a very specific mathematical term regarding a family of curves. This is not what we mean. Contour: this defines the edge of an object, and is a suitable term for function 1. Shape: this seems a good fit for function 2, as the shape of an object does not change just because it moves. Bounds: this seems a good fit for function 3, as bounds are generally perceived as min/max along a number of dimensions.

With locations given as OrientedPoint2d, this gives the following relationships: Shape + Location = Contour Bounds + Location = Bounds (possibly bigger due to ration)

What types are suitable? Contour For the most general case, this is a PolyLine2d as some objects are lines without width. Note that point objects have no contour or shape, only a location (although possibly expanded to some shape for clickability). More specific classes can specify Polygon2d as output, which extends PolyLine2d.

Shape Being defined relative to its origin, the contract with a shape is different from a contour. For example, in a contains(Point2d) method, the shape assumes the point to be translated to its own coordinate system. The origin does not need to be part of the shape (e.g. a donut). A shape can also be used for signed distance functions, which a PolyLine2d or Polygon2d do not have. Hence, a new class Shape is required, with two specific methods:

Bounds Bounds2d from DJUTILS fits this function perfectly, and is used as such in DSOL.

What this gives As the functions share much functionality, it is logical for them to have an inheritance relationship.

interface org.djutils.draw.bounds.Bounds<?, ?, ?> (DJUTILS)

interface org.djutils.draw.bounds.BoxBounds<?, ?, ?> extends Bounds (DJUTILS, new)

class org.djutils.draw.bounds.Bounds2 implements BoxBounds (DJUTILS)

interface Shape extends Bounds (OTS, currently called OtsBounds2d)

interface OtsLocatable extends Locatable (OTS)