001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.coor; 003 004import java.io.Serializable; 005import java.util.Objects; 006 007/** 008 * Polar coordinate. 009 * @since 13107 (extracted from {@code AlignInCircleAction}) 010 */ 011public class PolarCoor implements Serializable { 012 013 private static final long serialVersionUID = 1L; 014 015 /** 016 * Radial coordinate (distance from the pole). 017 */ 018 public final double radius; 019 020 /** 021 * Angular coordinate in radians. 022 */ 023 public final double angle; 024 025 /** 026 * Reference point (analogous to the origin of a Cartesian coordinate system). 027 */ 028 public final EastNorth pole; 029 030 /** 031 * Constructs a new {@code PolarCoor}, using {@code (0,0)} as pole. 032 * @param radius radial coordinate (distance from the pole) 033 * @param angle angular coordinate in radians 034 */ 035 public PolarCoor(double radius, double angle) { 036 this(radius, angle, new EastNorth(0, 0)); 037 } 038 039 /** 040 * Constructs a new {@code PolarCoor}. 041 * @param radius radial coordinate (distance from the pole) 042 * @param angle angular coordinate in radians 043 * @param pole reference point (analogous to the origin of a Cartesian coordinate system) 044 */ 045 public PolarCoor(double radius, double angle, EastNorth pole) { 046 this.radius = radius; 047 this.angle = angle; 048 this.pole = pole; 049 } 050 051 /** 052 * Constructs a new {@code PolarCoor} from an {@link EastNorth}, using {@code (0,0)} as pole. 053 * @param en east/north coordinates 054 */ 055 public PolarCoor(EastNorth en) { 056 this(en, new EastNorth(0, 0)); 057 } 058 059 /** 060 * Constructs a new {@code PolarCoor}. 061 * @param en east/north coordinates 062 * @param pole reference point (analogous to the origin of a Cartesian coordinate system) 063 */ 064 public PolarCoor(EastNorth en, EastNorth pole) { 065 this(en.distance(pole), computeAngle(en, pole), pole); 066 } 067 068 /** 069 * Compute polar angle between an east/north and the pole. 070 * @param en east/north coordinates 071 * @param pole reference point (analogous to the origin of a Cartesian coordinate system) 072 * @return polar angle in radians 073 */ 074 public static double computeAngle(EastNorth en, EastNorth pole) { 075 return Math.atan2(en.north() - pole.north(), en.east() - pole.east()); 076 } 077 078 /** 079 * Converts this {@code PolarCoor} to an {@link EastNorth} instance. 080 * @return a new {@code EastNorth} instance 081 */ 082 public EastNorth toEastNorth() { 083 return new EastNorth( 084 radius * Math.cos(angle) + pole.east(), 085 radius * Math.sin(angle) + pole.north()); 086 } 087 088 @Override 089 public int hashCode() { 090 return Objects.hash(radius, angle, pole); 091 } 092 093 @Override 094 public boolean equals(Object obj) { 095 if (this == obj) return true; 096 if (obj == null || getClass() != obj.getClass()) return false; 097 PolarCoor that = (PolarCoor) obj; 098 return Double.compare(that.radius, radius) == 0 && 099 Double.compare(that.angle, angle) == 0 && 100 Objects.equals(that.pole, pole); 101 } 102 103 @Override 104 public String toString() { 105 return "PolarCoor [radius=" + radius + ", angle=" + angle + ", pole=" + pole + ']'; 106 } 107}