1 // ******************************************************************************
2 //
3 // Title: Force Field X.
4 // Description: Force Field X - Software for Molecular Biophysics.
5 // Copyright: Copyright (c) Michael J. Schnieders 2001-2025.
6 //
7 // This file is part of Force Field X.
8 //
9 // Force Field X is free software; you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License version 3 as published by
11 // the Free Software Foundation.
12 //
13 // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 // details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20 // Place, Suite 330, Boston, MA 02111-1307 USA
21 //
22 // Linking this library statically or dynamically with other modules is making a
23 // combined work based on this library. Thus, the terms and conditions of the
24 // GNU General Public License cover the whole combination.
25 //
26 // As a special exception, the copyright holders of this library give you
27 // permission to link this library with independent modules to produce an
28 // executable, regardless of the license terms of these independent modules, and
29 // to copy and distribute the resulting executable under terms of your choice,
30 // provided that you also meet, for each linked independent module, the terms
31 // and conditions of the license of that module. An independent module is a
32 // module which is not derived from or based on this library. If you modify this
33 // library, you may extend this exception to your version of the library, but
34 // you are not obligated to do so. If you do not wish to do so, delete this
35 // exception statement from your version.
36 //
37 // ******************************************************************************
38 package ffx.numerics.math;
39
40 import static java.lang.System.arraycopy;
41
42 /**
43 * Convenience class for working with 3D double vectors.
44 *
45 * @author Michael J. Schnieders
46 * @since 1.0
47 */
48 public class Double3 {
49
50 /** Internal storage for the vector. */
51 private final double[] a;
52
53 /** Construct a Double3 at (0.0, 0.0, 0.0). */
54 public Double3() {
55 a = new double[] {0.0, 0.0, 0.0};
56 }
57
58 /**
59 * Construct a Double3 at (x, y, z).
60 *
61 * @param x X value.
62 * @param y Y value.
63 * @param z Z value.
64 */
65 public Double3(double x, double y, double z) {
66 a = new double[] {x, y, z};
67 }
68
69 /**
70 * Construct a Double3 at a.
71 *
72 * @param a Double3 to initialize from (the data is copied).
73 */
74 public Double3(double[] a) {
75 this.a = new double[] {a[0], a[1], a[2]};
76 }
77
78 /**
79 * Compute <code>this * b + c</code> and return the result in a new Double3.
80 *
81 * @param b Scalar.
82 * @param c Double3.
83 * @return Returns the FMA of <code>this * b + c</code> in a new Double3.
84 */
85 public Double3 fma(double b, Double3 c) {
86 Double3 ret = new Double3();
87 DoubleMath.fma(a, b, c.get(), ret.get());
88 return ret;
89 }
90
91 /**
92 * Compute <code>this * b + c</code> and return the result in a new Double3.
93 *
94 * @param b Scalar.
95 * @param c Double3.
96 * @return Returns the FMA of <code>this * b + c</code> in this Double3.
97 */
98 public Double3 fmaI(double b, Double3 c) {
99 DoubleMath.fma(a, b, c.get(), a);
100 return this;
101 }
102
103 /**
104 * Cross product of this Double3 with b.
105 *
106 * @param b Vector b.
107 * @return Returns the cross product in a new Double3.
108 */
109 public Double3 X(Double3 b) {
110 Double3 ret = new Double3();
111 DoubleMath.X(a, b.get(), ret.get());
112 return ret;
113 }
114
115 /**
116 * In-place Cross product of this Double3 with b.
117 *
118 * @param b Vector b.
119 * @return Returns the cross product in this Double3.
120 */
121 public Double3 XI(Double3 b) {
122 return set(X(b));
123 }
124
125 /**
126 * Finds the sum of this Double3 with b.
127 *
128 * @param b Second Double3.
129 * @return Returns the sum in a new Double3.
130 */
131 public Double3 add(Double3 b) {
132 Double3 ret = new Double3();
133 DoubleMath.add(a, b.get(), ret.get());
134 return ret;
135 }
136
137 /**
138 * Finds the sum of this Double3 with b in place.
139 *
140 * @param b Second Double3.
141 * @return Returns the sum in this Double3.
142 */
143 public Double3 addI(Double3 b) {
144 DoubleMath.add(a, b.get(), a);
145 return this;
146 }
147
148 /**
149 * Angle of this Double3 with b.
150 *
151 * @param b Vector b.
152 * @return Returns the angle.
153 */
154 public double angle(Double3 b) {
155 return DoubleMath.angle(a, b.get());
156 }
157
158 /**
159 * Returns a new copy of this Double3.
160 *
161 * @return Returns a copy of this Double3.
162 */
163 public Double3 copy() {
164 return new Double3(a);
165 }
166
167 /**
168 * Finds the Euclidean distance between two positions.
169 *
170 * @param b Second vector.
171 * @return Returns the distance between this Double3 and b.
172 */
173 public double dist(Double3 b) {
174 return DoubleMath.dist(a, b.get());
175 }
176
177 /**
178 * Finds the square of the Euclidean distance between two positions.
179 *
180 * @param b Second vector.
181 * @return Returns the squared distance between this Double3 and b.
182 */
183 public double dist2(Double3 b) {
184 return DoubleMath.dist2(a, b.get());
185 }
186
187 /**
188 * Finds the dot product between two vectors.
189 *
190 * @param b Second vector.
191 * @return Returns the dot product of this Double3 and b.
192 */
193 public double dot(Double3 b) {
194 return DoubleMath.dot(a, b.get());
195 }
196
197 /**
198 * Returns a reference to the internal double array that stores this Double3.
199 *
200 * @return A reference to the internal double array.
201 */
202 public double[] get() {
203 return a;
204 }
205
206 /**
207 * Returns the coordinate at position i.
208 *
209 * @param i The coordinate index.
210 * @return The coordinate.
211 */
212 public double get(int i) {
213 return a[i];
214 }
215
216 /**
217 * Finds the length of this Double3.
218 *
219 * @return Length of vector this Double3.
220 */
221 public double length() {
222 return DoubleMath.length(a);
223 }
224
225 /**
226 * Finds the length of this Double3 squared.
227 *
228 * @return Length of vector this Double3 squared.
229 */
230 public double length2() {
231 return DoubleMath.length2(a);
232 }
233
234 /** Log this Double3. */
235 public void log() {
236 DoubleMath.log(a);
237 }
238
239 /**
240 * Normalize this Double3.
241 *
242 * @return Returns a new Double3.
243 */
244 public Double3 normalize() {
245 Double3 ret = new Double3();
246 DoubleMath.normalize(a, ret.get());
247 return ret;
248 }
249
250 /**
251 * Normalize this Double3 in place.
252 *
253 * @return Returns a reference to this Double3 normalized.
254 */
255 public Double3 normalizeI() {
256 DoubleMath.normalize(a, a);
257 return this;
258 }
259
260 /**
261 * Scales a Double3.
262 *
263 * @param d A scalar value.
264 * @return Returns a new scaled Double3.
265 */
266 public Double3 scale(double d) {
267 Double3 ret = new Double3();
268 DoubleMath.scale(a, d, ret.get());
269 return ret;
270 }
271
272 /**
273 * Scales a Double3 in place.
274 *
275 * @param d A scalar value.
276 * @return Returns a reference to this Double3 scaled.
277 */
278 public Double3 scaleI(double d) {
279 DoubleMath.scale(a, d, a);
280 return this;
281 }
282
283 /**
284 * Squares values in Double3.
285 *
286 * @return Returns a reference to this Double3 squared.
287 */
288 public Double3 square() {
289 Double3 ret = new Double3();
290 DoubleMath.square(a, ret.get());
291 return ret;
292 }
293
294 /**
295 * Squares values in Double3 in place.
296 *
297 * @return Returns a reference to this Double3 squared.
298 */
299 public Double3 squareI() {
300 DoubleMath.square(a, a);
301 return this;
302 }
303
304 /**
305 * Square roots values in Double3.
306 *
307 * @return Returns a reference to this Double3 square rooted.
308 */
309 public Double3 sqrt() {
310 Double3 ret = new Double3();
311 DoubleMath.squareRoot(a, ret.get());
312 return ret;
313 }
314
315 /**
316 * Square roots values in Double3 in place.
317 *
318 * @return Returns a reference to this Double3 square rooted.
319 */
320 public Double3 sqrtI() {
321 DoubleMath.squareRoot(a, a);
322 return this;
323 }
324
325 /**
326 * Set the value of this Double3.
327 *
328 * @param x X-value.
329 * @param y Y-value.
330 * @param z Z-value.
331 * @return A reference to this Double3.
332 */
333 public Double3 set(double x, double y, double z) {
334 a[0] = x;
335 a[1] = y;
336 a[2] = z;
337 return this;
338 }
339
340 /**
341 * Set the value of this Double3.
342 *
343 * @param b Double array that is copied.
344 * @return A reference to this Double3.
345 */
346 public Double3 set(double[] b) {
347 arraycopy(b, 0, a, 0, 3);
348 return this;
349 }
350
351 /**
352 * Set the value of this Double3.
353 *
354 * @param b Double3 that is copied.
355 * @return A reference to this Double3.
356 */
357 public Double3 set(Double3 b) {
358 arraycopy(b.get(), 0, a, 0, 3);
359 return this;
360 }
361
362 /**
363 * Finds the difference between two vectors.
364 *
365 * @param b Second vector
366 * @return Returns the difference in a new Double3.
367 */
368 public Double3 sub(Double3 b) {
369 Double3 ret = new Double3();
370 DoubleMath.sub(a, b.get(), ret.get());
371 return ret;
372 }
373
374 /**
375 * Finds the difference between two vectors.
376 *
377 * @param b Second vector
378 * @return Returns the difference in this Double3.
379 */
380 public Double3 subI(Double3 b) {
381 DoubleMath.sub(a, b.get(), a);
382 return this;
383 }
384
385 /**
386 * Describe this Double3 in a String.
387 *
388 * @return Returns a String description.
389 */
390 @Override
391 public String toString() {
392 return DoubleMath.toString(a);
393 }
394
395 /**
396 * Get the value x.
397 *
398 * @return Returns x.
399 */
400 public double x() {
401 return a[0];
402 }
403
404 /**
405 * Get the value of y.
406 *
407 * @return Returns y.
408 */
409 public double y() {
410 return a[1];
411 }
412
413 /**
414 * Get the value of z.
415 *
416 * @return Returns z.
417 */
418 public double z() {
419 return a[2];
420 }
421 }