View Javadoc

    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
    19  import org.apache.commons.geometry.core.Point;
    20  import org.apache.commons.geometry.core.Vector;
    21  import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
    22  import org.apache.commons.geometry.euclidean.internal.Vectors;
    23
    24  /** Abstract base class for Euclidean vectors <em>and</em> points. See
    25   * {@link org.apache.commons.geometry.euclidean here} for a discussion
    26   * of the combination of point and vector functionality into a single
    27   * class hierarchy.
    28   *
    29   * @param <V> Vector implementation type
    30   */
    31  public abstract class EuclideanVector<V extends EuclideanVector<V>>
    32      implements Vector<V>, Point<V> {
    33
    34      /** Return the vector representing the displacement from this vector
    35       * to the given vector. This is exactly equivalent to {@code v.subtract(thisVector)}
    36       * but with a method name that is much easier to visualize.
    37       * @param v the vector that the returned vector will be directed toward
    38       * @return vector representing the displacement <em>from</em> this vector <em>to</em> the given vector
    39       */
    40      public abstract V vectorTo(V v);
    41
    42      /** Return the unit vector representing the direction of displacement from this
    43       * vector to the given vector. This is exactly equivalent to {@code v.subtract(thisVector).normalize()}
    44       * but without the intermediate vector instance.
    45       * @param v the vector that the returned vector will be directed toward
    46       * @return unit vector representing the direction of displacement <em>from</em> this vector
    47       *      <em>to</em> the given vector
    48       * @throws IllegalArgumentException if the norm of the vector pointing
    49       *      from this instance to {@code v} is zero, NaN, or infinite
    50       */
    51      public abstract V directionTo(V v);
    52
    53      /** Get a vector constructed by linearly interpolating between this vector and the given vector.
    54       * The vector coordinates are generated by the equation {@code V = (1 - t)*A + t*B}, where {@code A}
    55       * is the current vector and {@code B} is the given vector. This means that if {@code t = 0}, a
    56       * vector equal to the current vector will be returned. If {@code t = 1}, a vector equal to the
    57       * argument will be returned. The {@code t} parameter is not constrained to the range {@code [0, 1]},
    58       * meaning that linear extrapolation can also be performed with this method.
    59       * @param v other vector
    60       * @param t interpolation parameter
    61       * @return interpolated or extrapolated vector
    62       */
    63      public abstract V lerp(V v, double t);
    64
    65      /** Return true if the current instance and given vector are considered equal as evaluated by the
    66       * given precision context.
    67       *
    68       * <p>Equality is determined by comparing each pair of components in turn from the two
    69       * vectors. If all components evaluate as equal, then the vectors are considered equal. If any are
    70       * not equal, then the vectors are not considered equal. Note that this approach means that the
    71       * calculated distance between two "equal" vectors may be as much as <code>&radic;(n * eps<sup>2</sup>)</code>,
    72       * where {@code n} is the number of components in the vector and {@code eps} is the maximum epsilon
    73       * value allowed by the precision context.
    74       * @param v vector to check for equality
    75       * @param precision precision context used to determine floating point equality
    76       * @return true if the current instance is considered equal to the given vector when using
    77       *      the given precision context; otherwise false
    78       */
    79      public abstract boolean eq(V v, DoublePrecisionContext precision);
    80
    81      /** Return true if the current instance is considered equal to the zero vector as evaluated by the
    82       * given precision context. This is a convenience method equivalent to
    83       * {@code vec.equals(vec.getZero(), precision)}.
    84       *
    85       * @param precision precision context used to determine floating point equality
    86       * @return true if the current instance is considered equal to the zero vector when using
    87       *      the given precision context; otherwise false
    88       * @see #eq(EuclideanVector, DoublePrecisionContext)
    89       */
    90      public boolean isZero(final DoublePrecisionContext precision) {
    91          return eq(getZero(), precision);
    92      }
    93
    94      /** Return the vector norm value, throwing an {@link IllegalArgumentException} if the value is not real
    95       * (ie, NaN or infinite) or zero.
    96       * @return the vector norm value, guaranteed to be real and non-zero
    97       * @throws IllegalArgumentException if the vector norm is zero, NaN, or infinite
    98       */
    99      protected double getCheckedNorm() {
    100         return Vectors.checkedNorm(this);
    101     }
    102 }