908d4454ef5001804afd2588a814192288c0fd73
[debian/openrocket] / 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         public Point(int dim) {
20                 if (dim <= 0) {
21                         throw new IllegalArgumentException("Invalid dimensionality " + dim);
22                 }
23                 point = new double[dim];
24         }
25         
26         public Point(int dim, double value) {
27                 this(dim);
28                 Arrays.fill(point, value);
29         }
30         
31         public Point(double... value) {
32                 if (value.length == 0) {
33                         throw new IllegalArgumentException("Zero-dimensional point not allowed");
34                 }
35                 point = value.clone();
36         }
37         
38         private Point(Point p) {
39                 point = p.point.clone();
40         }
41         
42         
43
44         /**
45          * Return the point dimensionality.
46          * 
47          * @return      the point dimensionality
48          */
49         public int dim() {
50                 return point.length;
51         }
52         
53         
54
55         public double get(int i) {
56                 return point[i];
57         }
58         
59         public Point set(int i, double v) {
60                 Point p = new Point(this);
61                 p.point[i] = v;
62                 return p;
63         }
64         
65         
66         /**
67          * Return a new point that is the sum of two points.
68          * 
69          * @param other         the point to add to this point.
70          * @return                      the sum of these points.
71          */
72         public Point add(Point other) {
73                 Point p = new Point(this);
74                 for (int i = 0; i < point.length; i++) {
75                         p.point[i] += other.point[i];
76                 }
77                 return p;
78         }
79         
80         
81         /**
82          * Return a new point that is the subtraction of two points.
83          * 
84          * @param other         the point to subtract from this point.
85          * @return                      the value of this - other.
86          */
87         public Point sub(Point other) {
88                 Point p = new Point(this);
89                 for (int i = 0; i < point.length; i++) {
90                         p.point[i] -= other.point[i];
91                 }
92                 return p;
93         }
94         
95         
96         /**
97          * Return this point multiplied by a scalar value.
98          * 
99          * @param v             the scalar to multiply with
100          * @return              the scaled point
101          */
102         public Point mul(double v) {
103                 Point p = new Point(this);
104                 for (int i = 0; i < point.length; i++) {
105                         p.point[i] *= v;
106                 }
107                 return p;
108         }
109         
110         
111         /**
112          * Return the length of this coordinate.
113          * 
114          * @return      the length.
115          */
116         public double length() {
117                 if (length < 0) {
118                         length = Math.sqrt(length2());
119                 }
120                 return length;
121         }
122         
123         
124         /**
125          * Return the squared length of this coordinate.
126          * 
127          * @return      the square of the length of thie coordinate.
128          */
129         public double length2() {
130                 if (length2 < 0) {
131                         length2 = 0;
132                         for (double p : point) {
133                                 length2 += p * p;
134                         }
135                 }
136                 return length2;
137         }
138         
139         
140         /**
141          * Return the point as an array.
142          * 
143          * @return      the point as an array.
144          */
145         public double[] asArray() {
146                 return point.clone();
147         }
148         
149         @Override
150         public boolean equals(Object obj) {
151                 if (this == obj)
152                         return true;
153                 
154                 if (!(obj instanceof Point))
155                         return false;
156                 
157                 Point other = (Point) obj;
158                 if (this.point.length != other.point.length)
159                         return false;
160                 
161                 for (int i = 0; i < point.length; i++) {
162                         if (!MathUtil.equals(this.point[i], other.point[i]))
163                                 return false;
164                 }
165                 return true;
166         }
167         
168         @Override
169         public int hashCode() {
170                 int n = 0;
171                 for (double d : point) {
172                         n *= 37;
173                         n += (int) (d * 1000);
174                 }
175                 return n;
176         }
177         
178         @Override
179         public String toString() {
180                 return "Point" + Arrays.toString(point);
181         }
182 }