EuclideanVector.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.geometry.euclidean;

  18. import org.apache.commons.geometry.core.Point;
  19. import org.apache.commons.geometry.core.Vector;
  20. import org.apache.commons.geometry.euclidean.internal.Vectors;
  21. import org.apache.commons.numbers.core.Precision;

  22. /** Abstract base class for Euclidean vectors <em>and</em> points. See
  23.  * {@link org.apache.commons.geometry.euclidean here} for a discussion
  24.  * of the combination of point and vector functionality into a single
  25.  * class hierarchy.
  26.  *
  27.  * @param <V> Vector implementation type
  28.  */
  29. public abstract class EuclideanVector<V extends EuclideanVector<V>>
  30.     implements Vector<V>, Point<V> {

  31.     /** Return the vector representing the displacement from this vector
  32.      * to the given vector. This is exactly equivalent to {@code v.subtract(thisVector)}
  33.      * but with a method name that is much easier to visualize.
  34.      * @param v the vector that the returned vector will be directed toward
  35.      * @return vector representing the displacement <em>from</em> this vector <em>to</em> the given vector
  36.      */
  37.     public abstract V vectorTo(V v);

  38.     /** Return the unit vector representing the direction of displacement from this
  39.      * vector to the given vector. This is exactly equivalent to {@code v.subtract(thisVector).normalize()}
  40.      * but without the intermediate vector instance.
  41.      * @param v the vector that the returned vector will be directed toward
  42.      * @return unit vector representing the direction of displacement <em>from</em> this vector
  43.      *      <em>to</em> the given vector
  44.      * @throws IllegalArgumentException if the norm of the vector pointing
  45.      *      from this instance to {@code v} is zero, NaN, or infinite
  46.      */
  47.     public abstract V directionTo(V v);

  48.     /** Get a vector constructed by linearly interpolating between this vector and the given vector.
  49.      * The vector coordinates are generated by the equation {@code V = (1 - t)*A + t*B}, where {@code A}
  50.      * is the current vector and {@code B} is the given vector. This means that if {@code t = 0}, a
  51.      * vector equal to the current vector will be returned. If {@code t = 1}, a vector equal to the
  52.      * argument will be returned. The {@code t} parameter is not constrained to the range {@code [0, 1]},
  53.      * meaning that linear extrapolation can also be performed with this method.
  54.      * @param v other vector
  55.      * @param t interpolation parameter
  56.      * @return interpolated or extrapolated vector
  57.      */
  58.     public abstract V lerp(V v, double t);

  59.     /** Return true if the current instance and given vector are considered equal as evaluated by the
  60.      * given precision context.
  61.      *
  62.      * <p>Equality is determined by comparing each pair of components in turn from the two
  63.      * vectors. If all components evaluate as equal, then the vectors are considered equal. If any are
  64.      * not equal, then the vectors are not considered equal. Note that this approach means that the
  65.      * calculated distance between two "equal" vectors may be as much as <code>&radic;(n * eps<sup>2</sup>)</code>,
  66.      * where {@code n} is the number of components in the vector and {@code eps} is the maximum epsilon
  67.      * value allowed by the precision context.
  68.      * @param v vector to check for equality
  69.      * @param precision precision context used to determine floating point equality
  70.      * @return true if the current instance is considered equal to the given vector when using
  71.      *      the given precision context; otherwise false
  72.      */
  73.     public abstract boolean eq(V v, Precision.DoubleEquivalence precision);

  74.     /** Return true if the current instance is considered equal to the zero vector as evaluated by the
  75.      * given precision context. This is a convenience method equivalent to
  76.      * {@code vec.equals(vec.getZero(), precision)}.
  77.      *
  78.      * @param precision precision context used to determine floating point equality
  79.      * @return true if the current instance is considered equal to the zero vector when using
  80.      *      the given precision context; otherwise false
  81.      * @see #eq(EuclideanVector, Precision.DoubleEquivalence)
  82.      */
  83.     public boolean isZero(final Precision.DoubleEquivalence precision) {
  84.         return eq(getZero(), precision);
  85.     }

  86.     /** Return the vector norm value, throwing an {@link IllegalArgumentException} if the value is not real
  87.      * (ie, NaN or infinite) or zero.
  88.      * @return the vector norm value, guaranteed to be real and non-zero
  89.      * @throws IllegalArgumentException if the vector norm is zero, NaN, or infinite
  90.      */
  91.     protected double getCheckedNorm() {
  92.         return Vectors.checkedNorm(this);
  93.     }
  94. }