create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / optimization / general / Point.java
1 package net.sf.openrocket.optimization.general;
2
3 import java.util.Arrays;
4
5 import net.sf.openrocket.util.MathUtil;
6
7 /**
8  * An immutable n-dimensional coordinate point.
9  * 
10  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
11  */
12 public final class Point {
13         
14         private final double[] point;
15         private double length = -1;
16         private double length2 = -1;
17         
18         
19         /**
20          * Create a new point with all values zero.
21          * 
22          * @param dim   the dimensionality of the point
23          */
24         public Point(int dim) {
25                 if (dim <= 0) {
26                         throw new IllegalArgumentException("Invalid dimensionality " + dim);
27                 }
28                 point = new double[dim];
29         }
30         
31         
32         /**
33          * Create a new point filled with a specific value.
34          * 
35          * @param dim           the dimensionality of the point
36          * @param value         the value for all dimensions
37          */
38         public Point(int dim, double value) {
39                 this(dim);
40                 Arrays.fill(point, value);
41         }
42         
43         
44         /**
45          * Create a new point with specific values.
46          * 
47          * @param value         the values of the dimensions.
48          */
49         public Point(double... value) {
50                 if (value.length == 0) {
51                         throw new IllegalArgumentException("Zero-dimensional point not allowed");
52                 }
53                 point = value.clone();
54         }
55         
56         
57         /**
58          * Create a copy of a point.  Used locally to create copies.
59          * 
60          * @param p             the point to copy.
61          */
62         private Point(Point p) {
63                 point = p.point.clone();
64         }
65         
66         
67
68         /**
69          * Return the point dimensionality.
70          * 
71          * @return      the point dimensionality
72          */
73         public int dim() {
74                 return point.length;
75         }
76         
77         
78
79         public double get(int i) {
80                 return point[i];
81         }
82         
83         public Point set(int i, double v) {
84                 Point p = new Point(this);
85                 p.point[i] = v;
86                 return p;
87         }
88         
89         
90         /**
91          * Return a new point that is the sum of two points.
92          * 
93          * @param other         the point to add to this point.
94          * @return                      the sum of these points.
95          */
96         public Point add(Point other) {
97                 Point p = new Point(this);
98                 for (int i = 0; i < point.length; i++) {
99                         p.point[i] += other.point[i];
100                 }
101                 return p;
102         }
103         
104         
105         /**
106          * Return a new point that is the subtraction of two points.
107          * 
108          * @param other         the point to subtract from this point.
109          * @return                      the value of this - other.
110          */
111         public Point sub(Point other) {
112                 Point p = new Point(this);
113                 for (int i = 0; i < point.length; i++) {
114                         p.point[i] -= other.point[i];
115                 }
116                 return p;
117         }
118         
119         
120         /**
121          * Return this point multiplied by a scalar value.
122          * 
123          * @param v             the scalar to multiply with
124          * @return              the scaled point
125          */
126         public Point mul(double v) {
127                 Point p = new Point(this);
128                 for (int i = 0; i < point.length; i++) {
129                         p.point[i] *= v;
130                 }
131                 return p;
132         }
133         
134         
135         /**
136          * Return the length of this coordinate.
137          * 
138          * @return      the length.
139          */
140         public double length() {
141                 if (length < 0) {
142                         length = MathUtil.safeSqrt(length2());
143                 }
144                 return length;
145         }
146         
147         
148         /**
149          * Return the squared length of this coordinate.
150          * 
151          * @return      the square of the length of thie coordinate.
152          */
153         public double length2() {
154                 if (length2 < 0) {
155                         length2 = 0;
156                         for (double p : point) {
157                                 length2 += p * p;
158                         }
159                 }
160                 return length2;
161         }
162         
163         
164
165         /**
166          * Return the point as an array.
167          * 
168          * @return      the point as an array.
169          */
170         public double[] asArray() {
171                 return point.clone();
172         }
173         
174         @Override
175         public boolean equals(Object obj) {
176                 if (this == obj)
177                         return true;
178                 
179                 if (!(obj instanceof Point))
180                         return false;
181                 
182                 Point other = (Point) obj;
183                 if (this.point.length != other.point.length)
184                         return false;
185                 
186                 for (int i = 0; i < point.length; i++) {
187                         if (!MathUtil.equals(this.point[i], other.point[i]))
188                                 return false;
189                 }
190                 return true;
191         }
192         
193         @Override
194         public int hashCode() {
195                 int n = 0;
196                 for (double d : point) {
197                         n *= 37;
198                         n += (int) (d * 1000);
199                 }
200                 return n;
201         }
202         
203         @Override
204         public String toString() {
205                 return "Point" + Arrays.toString(point);
206         }
207 }