001package squidpony.squidmath;
002
003import java.io.Serializable;
004
005/**
006 * Coord using double values for x and y instead of int. Not pooled.
007 * When possible and you are using libGDX, use the {@code com.badlogic.gdx.math.Vector2} class in preference to this
008 * one if you are OK with using floats instead of doubles.
009 * <br>
010 * Created by Tommy Ettinger on 8/12/2015.
011 */
012public class CoordDouble implements Serializable {
013    private static final long serialVersionUID = 500L;
014    public double x;
015    public double y;
016
017    public CoordDouble()
018    {
019        this(0, 0);
020    }
021    public CoordDouble(double x, double y)
022    {
023        this.x = x;
024        this.y = y;
025    }
026    public CoordDouble(CoordDouble other)
027    {
028        x = other.x;
029        y = other.y;
030    }
031
032    public CoordDouble(Coord other)
033    {
034        x = other.x;
035        y = other.y;
036    }
037    public static CoordDouble get(double x, double y)
038    {
039        return new CoordDouble(x, y);
040    }
041
042    /**
043     * Constructs an identical copy to this CoordDouble, making a new object that may be mutated independently.
044     * @return a copy of this CoordDouble
045     */
046    public CoordDouble copy()
047    {
048        return new CoordDouble(x, y);
049    }
050
051    public CoordDouble add(double x, double y)
052    {
053        this.x += x;
054        this.y += y;
055        return this;
056    }
057
058    public CoordDouble add(CoordDouble other)
059    {
060        this.x += other.x;
061        this.y += other.y;
062        return this;
063    }
064
065    public CoordDouble subtract(double x, double y)
066    {
067        this.x -= x;
068        this.y -= y;
069        return this;
070    }
071
072    public CoordDouble subtract(CoordDouble other)
073    {
074        this.x -= other.x;
075        this.y -= other.y;
076        return this;
077    }
078
079    public CoordDouble multiply(double x, double y)
080    {
081        this.x *= x;
082        this.y *= y;
083        return this;
084    }
085
086    public CoordDouble multiply(CoordDouble other)
087    {
088        this.x *= other.x;
089        this.y *= other.y;
090        return this;
091    }
092
093    /**
094     * Divides the x component of this CoordDouble by {@code x} and the y component by {@code y}. Be careful about when
095     * either of the parameters can be 0.0, since that can put NaN or infinite components in this.
096     * @param x divisor for x
097     * @param y divisor for y
098     */
099    public CoordDouble divide(double x, double y)
100    {
101        this.x /= x;
102        this.y /= y;
103        return this;
104    }
105
106    /**
107     * Divides the x component of this CoordDouble by {@code other.x} and the y component by {@code other.y}. Be careful
108     * about when either of other's components can be 0.0, since that can put NaN or infinite components in this.
109     * @param other a non-null CoordDouble to get divisors from
110     */
111    public CoordDouble divide(CoordDouble other)
112    {
113        this.x /= other.x;
114        this.y /= other.y;
115        return this;
116    }
117
118    /**
119     * Gets the dot product of this CoordDouble and {@code other}.
120     * @param other another CoordDouble; must not be null.
121     * @return the dot product of this and {@code other}.
122     */
123    public double dot(CoordDouble other)
124    {
125        return x * other.x + y * other.y;
126    }
127
128    /**
129     * Gets the cross product of this CoordDouble and {@code other}.
130     * @param other another CoordDouble; must not be null.
131     * @return the cross product of this and {@code other}.
132     */
133    public double cross(CoordDouble other)
134    {
135        return y * other.x - x * other.y;
136    }
137    
138    public CoordDouble set(double x, double y)
139    {
140        this.x = x;
141        this.y = y;
142        return this;
143    }
144    public CoordDouble set(CoordDouble co)
145    {
146        x = co.x;
147        y = co.y;
148        return this;
149    }
150    /**
151     * Distance from the origin to this CoordDouble.
152     * @return the distance from the origin to this CoordDouble.
153     */
154    public double length()
155    {
156        return Math.sqrt(x * x + y * y);
157    }
158
159    /**
160     * Distance from the origin to this CoordDouble, squared.
161     * @return the distance from the origin to this CoordDouble, squared.
162     */
163    public double lengthSq()
164    {
165        return (x * x + y * y);
166    }
167    public double distance(double x2, double y2)
168    {
169        return Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y));
170    }
171    public double distance(CoordDouble co)
172    {
173        return Math.sqrt((co.x - x) * (co.x - x) + (co.y - y) * (co.y - y));
174    }
175    public double distanceSq(double x2, double y2)
176    {
177        return (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y);
178    }
179    public double distanceSq(CoordDouble co)
180    {
181        return (co.x - x) * (co.x - x) + (co.y - y) * (co.y - y);
182    }
183
184    public double getX() {
185        return x;
186    }
187
188    public void setX(double x) {
189        this.x = x;
190    }
191
192    public double getY() {
193        return y;
194    }
195
196    public void setY(double y) {
197        this.y = y;
198    }
199
200    @Override
201        public String toString()
202    {
203        return "CoordDouble (x " + x + ", y " + y + ")";
204    }
205
206        @Override
207        public int hashCode() {
208                return 31 * (31 + NumberTools.doubleToMixedIntBits(x)) + NumberTools.doubleToMixedIntBits(y) | 0;
209        }
210
211    @Override
212    public boolean equals(Object o) {
213        if (o instanceof CoordDouble) {
214            CoordDouble other = (CoordDouble) o;
215            return x == other.x && y == other.y;
216        } else {
217            return false;
218        }
219    }
220
221}