CircleShape.java
- package org.opentrafficsim.base.geometry;
- import java.util.Iterator;
- import java.util.NoSuchElementException;
- import org.djutils.draw.line.Polygon2d;
- import org.djutils.draw.point.Point2d;
- import org.djutils.exceptions.Throw;
- /**
- * Shape defined by a circle.
- * <p>
- * Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
- * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
- * </p>
- * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
- */
- public class CircleShape implements OtsShape
- {
- /** Radius. */
- private final double radius;
- /** Number of line segments in polygon representation. */
- private final int polygonSegments;
- /** Polygon representation. */
- private Polygon2d polygon;
- /**
- * Constructor.
- * @param radius radius.
- */
- public CircleShape(final double radius)
- {
- this(radius, DEFAULT_POLYGON_SEGMENTS);
- }
- /**
- * Constructor.
- * @param radius radius.
- * @param polygonSegments number of segments in polygon representation.
- */
- public CircleShape(final double radius, final int polygonSegments)
- {
- Throw.whenNull(radius, "Radius must not be null.");
- Throw.when(radius <= 0.0, IllegalArgumentException.class, "Radius must be above 0.0.");
- this.radius = radius;
- this.polygonSegments = polygonSegments;
- }
- @Override
- public double getMinX()
- {
- return -this.radius;
- }
- @Override
- public double getMaxX()
- {
- return this.radius;
- }
- @Override
- public double getMinY()
- {
- return -this.radius;
- }
- @Override
- public double getMaxY()
- {
- return this.radius;
- }
- @Override
- public boolean contains(final Point2d point) throws NullPointerException
- {
- return CENTER.distance(point) < this.radius;
- }
- @Override
- public boolean contains(final double x, final double y)
- {
- return contains(new Point2d(x, y));
- }
- @Override
- public double signedDistance(final Point2d point)
- {
- return CENTER.distance(point) - this.radius;
- }
- @Override
- public Polygon2d asPolygon()
- {
- if (this.polygon == null)
- {
- if (this.radius == 0.0)
- {
- this.polygon = new Polygon2d(false, new Point2d(0.0, 0.0));
- }
- else
- {
- this.polygon = new Polygon2d(new Iterator<Point2d>()
- {
- /** Step. */
- private int step = 0;
- @Override
- public boolean hasNext()
- {
- return this.step <= CircleShape.this.polygonSegments;
- }
- @Override
- public Point2d next()
- {
- Throw.when(!hasNext(), NoSuchElementException.class, "Iterator has no more elements.");
- // at full circle (this.step == polygonSegments), make sure end point is exactly the same as the start
- // point
- double ang = this.step == CircleShape.this.polygonSegments ? 0.0
- : (2.0 * Math.PI * this.step) / CircleShape.this.polygonSegments;
- this.step++;
- return new Point2d(Math.cos(ang) * CircleShape.this.radius, Math.sin(ang) * CircleShape.this.radius);
- }
- });
- }
- }
- return this.polygon;
- }
- @Override
- public String toString()
- {
- return "CircleShape [radius=" + this.radius + "]";
- }
- }