View Javadoc
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 float vectors.
44   *
45   * @author Michael J. Schnieders
46   * @since 1.0
47   */
48  public class Float3 {
49  
50    /** Internal storage for the vector. */
51    private final float[] a;
52  
53    /** Construct a Float3 at (0.0, 0.0, 0.0). */
54    public Float3() {
55      a = new float[] {0.0f, 0.0f, 0.0f};
56    }
57  
58    /**
59     * Construct a Float3 at (x, y, z).
60     *
61     * @param x X value.
62     * @param y Y value.
63     * @param z Z value.
64     */
65    public Float3(float x, float y, float z) {
66      a = new float[] {x, y, z};
67    }
68  
69    /**
70     * Construct a Float3 at a.
71     *
72     * @param a Float3 to initialize from (the data is copied).
73     */
74    public Float3(float[] a) {
75      this.a = new float[] {a[0], a[1], a[2]};
76    }
77  
78    /**
79     * Compute a * b + c and return the result in a new Float3.
80     *
81     * @param b Scalar.
82     * @param c Float3.
83     * @return Returns the FMA of a * b + c in a new Float3.
84     */
85    public Float3 fma(float b, Float3 c) {
86      Float3 ret = new Float3();
87      FloatMath.fma(a, b, c.get(), ret.get());
88      return ret;
89    }
90  
91    /**
92     * Compute a * b + c and return the result in a new Float3.
93     *
94     * @param b Scalar.
95     * @param c Float3.
96     * @return Returns the FMA of a * b + c in a new Float3.
97     */
98    public Float3 fmaI(float b, Float3 c) {
99      FloatMath.fma(a, b, c.get(), a);
100     return this;
101   }
102 
103   /**
104    * Cross product of this Float3 with b.
105    *
106    * @param b Vector b.
107    * @return Returns the cross product in a new Float3.
108    */
109   public Float3 X(Float3 b) {
110     Float3 ret = new Float3();
111     FloatMath.X(a, b.get(), ret.get());
112     return ret;
113   }
114 
115   /**
116    * In-place Cross product of this Float3 with b.
117    *
118    * @param b Vector b.
119    * @return Returns the cross product in this Float3.
120    */
121   public Float3 XI(Float3 b) {
122     return set(X(b));
123   }
124 
125   /**
126    * Finds the sum of this Float3 with b.
127    *
128    * @param b Second Float3.
129    * @return Returns the sum in a new Float3.
130    */
131   public Float3 add(Float3 b) {
132     Float3 ret = new Float3();
133     FloatMath.add(a, b.get(), ret.get());
134     return ret;
135   }
136 
137   /**
138    * Finds the sum of this Float3 with b in place.
139    *
140    * @param b Second Float3.
141    * @return Returns the sum in this Float3.
142    */
143   public Float3 addI(Float3 b) {
144     FloatMath.add(a, b.get(), a);
145     return this;
146   }
147 
148   /**
149    * Angle of this Float3 with b.
150    *
151    * @param b Vector b.
152    * @return Returns the angle.
153    */
154   public float angle(Float3 b) {
155     return FloatMath.angle(a, b.get());
156   }
157 
158   /**
159    * Returns a new copy of this Float3.
160    *
161    * @return Returns a copy of this Float3.
162    */
163   public Float3 copy() {
164     return new Float3(a);
165   }
166 
167   /**
168    * Finds the distance between two vectors.
169    *
170    * @param b Second vector.
171    * @return Returns the distance between this Float3 and b.
172    */
173   public float dist(Float3 b) {
174     return FloatMath.dist(a, b.get());
175   }
176 
177   /**
178    * Finds the squared distance between two vectors
179    *
180    * @param b Second vector.
181    * @return Returns the squared distance between this Float3 and b.
182    */
183   public float dist2(Float3 b) {
184     return FloatMath.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 Float3 and b.
192    */
193   public float dot(Float3 b) {
194     return FloatMath.dot(a, b.get());
195   }
196 
197   /**
198    * Returns a reference to the internal float array that stores this Float3.
199    *
200    * @return A reference to the internal float array.
201    */
202   public float[] 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 float get(int i) {
213     return a[i];
214   }
215 
216   /**
217    * Finds the length of this Float3.
218    *
219    * @return Length of vector this Float3.
220    */
221   public float length() {
222     return FloatMath.length(a);
223   }
224 
225   /**
226    * Finds the length of this Float3 squared.
227    *
228    * @return Length of vector this Float3 squared.
229    */
230   public float length2() {
231     return FloatMath.length2(a);
232   }
233 
234   /** Log this Float3. */
235   public void log() {
236     FloatMath.log(a);
237   }
238 
239   /**
240    * Normalize this Float3.
241    *
242    * @return Returns the normalized vector in a new Float3.
243    */
244   public Float3 normalize() {
245     Float3 ret = new Float3();
246     FloatMath.normalize(a, ret.get());
247     return ret;
248   }
249 
250   /**
251    * Normalize this Float3 in place.
252    *
253    * @return Returns a reference to this Float3 normalized.
254    */
255   public Float3 normalizeI() {
256     FloatMath.normalize(a, a);
257     return this;
258   }
259 
260   /**
261    * Scales a Float3.
262    *
263    * @param d A scalar value.
264    * @return Returns a new scaled Float3.
265    */
266   public Float3 scale(float d) {
267     Float3 ret = new Float3();
268     FloatMath.scale(a, d, ret.get());
269     return ret;
270   }
271 
272   /**
273    * Scales a Float3 in place.
274    *
275    * @param d A scalar value.
276    * @return Returns a reference to this Float3 scaled.
277    */
278   public Float3 scaleI(float d) {
279     FloatMath.scale(a, d, a);
280     return this;
281   }
282 
283   /**
284    * Squares values in Float3.
285    *
286    * @return Returns a reference to this Float3 squared.
287    */
288   public Float3 square() {
289     Float3 ret = new Float3();
290     FloatMath.square(a, ret.get());
291     return ret;
292   }
293 
294   /**
295    * Squares values in Float3 in place.
296    *
297    * @return Returns a reference to this Float3 squared.
298    */
299   public Float3 squareI() {
300     FloatMath.square(a, a);
301     return this;
302   }
303 
304   /**
305    * Square roots values in Float3.
306    *
307    * @return Returns a reference to this Float3 square rooted.
308    */
309   public Float3 sqrt() {
310     Float3 ret = new Float3();
311     FloatMath.squareRoot(a, ret.get());
312     return ret;
313   }
314 
315   /**
316    * Square roots values in Float3 in place.
317    *
318    * @return Returns a reference to this Float3 square rooted.
319    */
320   public Float3 sqrtI() {
321     FloatMath.squareRoot(a, a);
322     return this;
323   }
324 
325   /**
326    * Set the value of this Float3.
327    *
328    * @param x X-value.
329    * @param y Y-value.
330    * @param z Z-value.
331    * @return A reference to this Float3.
332    */
333   public Float3 set(float x, float y, float 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 Float3.
342    *
343    * @param b Double array that is copied.
344    * @return A reference to this Float3.
345    */
346   public Float3 set(float[] b) {
347     arraycopy(b, 0, a, 0, 3);
348     return this;
349   }
350 
351   /**
352    * Set the value of this Float3.
353    *
354    * @param b Float3 that is copied.
355    * @return A reference to this Float3.
356    */
357   public Float3 set(Float3 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 Float3.
367    */
368   public Float3 sub(Float3 b) {
369     Float3 ret = new Float3();
370     FloatMath.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 Float3.
379    */
380   public Float3 subI(Float3 b) {
381     FloatMath.sub(a, b.get(), a);
382     return this;
383   }
384 
385   /**
386    * Describe this Float3 in a String.
387    *
388    * @return Returns a String description.
389    */
390   @Override
391   public String toString() {
392     return FloatMath.toString(a);
393   }
394 
395   /**
396    * Get the value x.
397    *
398    * @return Returns x.
399    */
400   public float x() {
401     return a[0];
402   }
403 
404   /**
405    * Get the value of y.
406    *
407    * @return Returns y.
408    */
409   public float y() {
410     return a[1];
411   }
412 
413   /**
414    * Get the value of z.
415    *
416    * @return Returns z.
417    */
418   public float z() {
419     return a[2];
420   }
421 }