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 CircleShape implements OtsShape
19 {
20
21
22 private final double radius;
23
24
25 private final int polygonSegments;
26
27
28 private Polygon2d polygon;
29
30
31
32
33
34 public CircleShape(final double radius)
35 {
36 this(radius, DEFAULT_POLYGON_SEGMENTS);
37 }
38
39
40
41
42
43
44 public CircleShape(final double radius, final int polygonSegments)
45 {
46 Throw.whenNull(radius, "Radius must not be null.");
47 Throw.when(radius <= 0.0, IllegalArgumentException.class, "Radius must be above 0.0.");
48 this.radius = radius;
49 this.polygonSegments = polygonSegments;
50 }
51
52 @Override
53 public double getMinX()
54 {
55 return -this.radius;
56 }
57
58 @Override
59 public double getMaxX()
60 {
61 return this.radius;
62 }
63
64 @Override
65 public double getMinY()
66 {
67 return -this.radius;
68 }
69
70 @Override
71 public double getMaxY()
72 {
73 return this.radius;
74 }
75
76 @Override
77 public boolean contains(final Point2d point) throws NullPointerException
78 {
79 return CENTER.distance(point) < this.radius;
80 }
81
82 @Override
83 public boolean contains(final double x, final double y)
84 {
85 return contains(new Point2d(x, y));
86 }
87
88 @Override
89 public double signedDistance(final Point2d point)
90 {
91 return CENTER.distance(point) - this.radius;
92 }
93
94 @Override
95 public Polygon2d asPolygon()
96 {
97 if (this.polygon == null)
98 {
99 if (this.radius == 0.0)
100 {
101 this.polygon = new Polygon2d(false, new Point2d(0.0, 0.0));
102 }
103 else
104 {
105 this.polygon = new Polygon2d(new Iterator<Point2d>()
106 {
107
108 private int step = 0;
109
110 @Override
111 public boolean hasNext()
112 {
113 return this.step <= CircleShape.this.polygonSegments;
114 }
115
116 @Override
117 public Point2d next()
118 {
119 Throw.when(!hasNext(), NoSuchElementException.class, "Iterator has no more elements.");
120
121
122 double ang = this.step == CircleShape.this.polygonSegments ? 0.0
123 : (2.0 * Math.PI * this.step) / CircleShape.this.polygonSegments;
124 this.step++;
125 return new Point2d(Math.cos(ang) * CircleShape.this.radius, Math.sin(ang) * CircleShape.this.radius);
126 }
127 });
128 }
129 }
130 return this.polygon;
131 }
132
133 @Override
134 public String toString()
135 {
136 return "CircleShape [radius=" + this.radius + "]";
137 }
138
139 }