1 package org.opentrafficsim.base.geometry;
2
3 import java.util.Iterator;
4 import java.util.NoSuchElementException;
5
6 import org.djutils.draw.line.Polygon2d;
7 import org.djutils.draw.point.Point2d;
8 import org.djutils.exceptions.Throw;
9
10
11
12
13
14
15
16
17
18 public class BoundingCircle implements OtsBounds2d
19 {
20
21
22 private final static int POLYGON_STEPS = 128;
23
24
25 private final double radius;
26
27
28 private Polygon2d polygon;
29
30
31
32
33
34 public BoundingCircle(final double radius)
35 {
36 Throw.whenNull(radius, "Radius must not be null.");
37 Throw.when(radius <= 0.0, IllegalArgumentException.class, "Radius must be above 0.0.");
38 this.radius = radius;
39 }
40
41
42 @Override
43 public double getMinX()
44 {
45 return -this.radius;
46 }
47
48
49 @Override
50 public double getMaxX()
51 {
52 return this.radius;
53 }
54
55
56 @Override
57 public double getMinY()
58 {
59 return -this.radius;
60 }
61
62
63 @Override
64 public double getMaxY()
65 {
66 return this.radius;
67 }
68
69
70 @Override
71 public boolean contains(final Point2d point) throws NullPointerException
72 {
73 return CENTER.distance(point) < this.radius;
74 }
75
76
77 @Override
78 public boolean covers(final Point2d point) throws NullPointerException
79 {
80 return CENTER.distance(point) <= this.radius;
81 }
82
83
84 @Override
85 public double signedDistance(final Point2d point)
86 {
87 return CENTER.distance(point) - this.radius;
88 }
89
90
91 @Override
92 public Polygon2d asPolygon()
93 {
94 if (this.polygon == null)
95 {
96 if (this.radius == 0.0)
97 {
98 this.polygon = new Polygon2d(false, new Point2d(0.0, 0.0));
99 }
100 else
101 {
102 this.polygon = new Polygon2d(new Iterator<Point2d>()
103 {
104
105 private int step = 0;
106
107
108 @Override
109 public boolean hasNext()
110 {
111 return this.step <= POLYGON_STEPS;
112 }
113
114
115 @Override
116 public Point2d next()
117 {
118 Throw.when(!hasNext(), NoSuchElementException.class, "Iterator has no more elements.");
119
120
121 double ang = this.step == POLYGON_STEPS ? 0.0 : (2.0 * Math.PI * this.step) / POLYGON_STEPS;
122 this.step++;
123 return new Point2d(Math.sin(ang) * BoundingCircle.this.radius,
124 Math.sin(ang) * BoundingCircle.this.radius);
125 }
126 });
127 }
128 }
129 return this.polygon;
130 }
131
132 }