// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.draw; import java.awt.Shape; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import java.util.Optional; import java.util.stream.Stream; /** * A list of possible symbol shapes. * @since 10875 */ public enum SymbolShape { /** * A square */ SQUARE("square", 4, Math.PI / 4), /** * A circle */ CIRCLE("circle", 1, 0), /** * A triangle with sides of equal lengh */ TRIANGLE("triangle", 3, Math.PI / 2), /** * A pentagon */ PENTAGON("pentagon", 5, Math.PI / 2), /** * A hexagon */ HEXAGON("hexagon", 6, 0), /** * A heptagon */ HEPTAGON("heptagon", 7, Math.PI / 2), /** * An octagon */ OCTAGON("octagon", 8, Math.PI / 8), /** * a nonagon */ NONAGON("nonagon", 9, Math.PI / 2), /** * A decagon */ DECAGON("decagon", 10, 0); private final String name; final int sides; final double rotation; SymbolShape(String name, int sides, double rotation) { this.name = name; this.sides = sides; this.rotation = rotation; } /** * Create the path for this shape around the given position * @param x The x position * @param y The y position * @param size The size (width for rect, diameter for rest) * @return The symbol. * @since 10875 */ public Shape shapeAround(double x, double y, double size) { double radius = size / 2; Shape shape; switch (this) { case SQUARE: // optimize for performance reasons shape = new Rectangle2D.Double(x - radius, y - radius, size, size); break; case CIRCLE: shape = new Ellipse2D.Double(x - radius, y - radius, size, size); break; default: shape = buildPolygon(x, y, radius); break; } return shape; } private Shape buildPolygon(double cx, double cy, double radius) { GeneralPath polygon = new GeneralPath(); for (int i = 0; i < sides; i++) { double angle = ((2 * Math.PI / sides) * i) - rotation; double x = cx + radius * Math.cos(angle); double y = cy + radius * Math.sin(angle); if (i == 0) { polygon.moveTo(x, y); } else { polygon.lineTo(x, y); } } polygon.closePath(); return polygon; } /** * Gets the number of normally straight sides this symbol has. Returns 1 for a circle. * @return The sides of the symbol */ public int getSides() { return sides; } /** * Gets the rotation of the first point of this symbol. * @return The rotation */ public double getRotation() { return rotation; } /** * Get the MapCSS name for this shape * @return The name */ public String getName() { return name; } /** * Get the shape with the given name * @param val The name to search * @return The shape as optional */ public static Optional<SymbolShape> forName(String val) { return Stream.of(values()).filter(shape -> val.equals(shape.name)).findAny(); } }