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 }