1 package org.opentrafficsim.base.geometry;
2
3 import org.djutils.draw.line.Polygon2d;
4 import org.djutils.draw.point.Point2d;
5
6 /**
7 * Shape representation of objects that is suitable for continuous spatial 2D algorithms. Default methods use the polygon
8 * representation of the shape. For many simple shapes there may be faster methods to determine information.
9 * <p>
10 * Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
11 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
12 * </p>
13 * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
14 */
15 public interface OtsShape
16 {
17
18 /** Standard mid point. */
19 Point2d CENTER = new Point2d(0.0, 0.0);
20
21 /** Default number of segments in polygon. */
22 int DEFAULT_POLYGON_SEGMENTS = 128;
23
24 /**
25 * Return the absolute lower bound for x.
26 * @return double; the absolute lower bound for x
27 */
28 default double getMinX()
29 {
30 return asPolygon().getBounds().getMinX();
31 }
32
33 /**
34 * Return the absolute upper bound for x.
35 * @return double; the absolute upper bound for x
36 */
37 default double getMaxX()
38 {
39 return asPolygon().getBounds().getMaxX();
40 }
41
42 /**
43 * Return the absolute lower bound for y.
44 * @return double; the absolute lower bound for y
45 */
46 default double getMinY()
47 {
48 return asPolygon().getBounds().getMinY();
49 }
50
51 /**
52 * Return the absolute upper bound for y.
53 * @return double; the absolute upper bound for y
54 */
55 default double getMaxY()
56 {
57 return asPolygon().getBounds().getMaxY();
58 }
59
60 /**
61 * Return the extent of this Bounds2d in the x-direction.
62 * @return double; the extent of this Bounds2d in the x-direction
63 */
64 default double getDeltaX()
65 {
66 return getMaxX() - getMinX();
67 }
68
69 /**
70 * Return the extent of this Bounds2d in the y-direction.
71 * @return double; the extent of this Bounds2d in the y-direction
72 */
73 default double getDeltaY()
74 {
75 return getMaxY() - getMinY();
76 }
77
78 /**
79 * Return the mid point of this Bounds object.
80 * @return P; the mid point of this Bounds object
81 */
82 default Point2d midPoint()
83 {
84 return CENTER;
85 }
86
87 /**
88 * Check if a point is contained in this OtsShape.
89 * @param point the point
90 * @return true if the point is within this OtsShape; false if the point is not within this OtsShape. Results may be
91 * ill-defined for points on the edges of this Polygon.
92 */
93 default boolean contains(final Point2d point)
94 {
95 return contains(point.x, point.y);
96 }
97
98 /**
99 * Check if a point is contained in this OtsShape.
100 * @param x x-coordinate
101 * @param y y-coordinate
102 * @return true if the point is within this OtsShape; false if the point is not within this OtsShape. Results may be
103 * ill-defined for points on the edges of this Polygon.
104 */
105 default boolean contains(final double x, final double y)
106 {
107 // do not use signedDistance(), it uses this function
108 return asPolygon().contains(x, y);
109 }
110
111 /**
112 * Returns a polygon representation of the bounds, such that an intersection can be derived.
113 * @return polygon representation of the bounds.
114 */
115 Polygon2d asPolygon();
116
117 /**
118 * Signed distance function. The coordinates must be transformed to this bound's space. Negative distances returned are
119 * inside the bounds, with the absolute value of the distance towards the edge. The default implementation is based on the
120 * polygon representation and is expensive.
121 * @param point point for which distance is returned.
122 * @return distance from point to these bounds.
123 */
124 default double signedDistance(final Point2d point)
125 {
126 double dist = asPolygon().closestPointOnPolyLine(point).distance(point);
127 return contains(point) ? -dist : dist;
128 }
129
130 }