blob: a55b1b778f8057bd85e11c0bbf62505a8bab4b15 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.geometry.core;
import org.apache.commons.geometry.core.exception.IllegalNormException;
/** Interface representing a vector in a vector space or displacement vectors
* in an affine space.
*
* <p>This interface uses self-referencing generic parameters to ensure
* that implementations are only used with instances of their own type.
* This removes the need for casting inside of methods in order to access
* implementation-specific data, such as coordinate values.
* </p>
*
* @see <a href="https://en.wikipedia.org/wiki/Vector_space">Vector space</a>
* @see <a href="https://en.wikipedia.org/wiki/Affine_space">Affine space</a>
*
* @param <V> Vector implementation type
*/
public interface Vector<V extends Vector<V>> extends Spatial {
/** Get the zero (null) vector of the space.
* @return zero vector of the space
*/
V getZero();
/** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector.
* This corresponds to the common notion of vector magnitude or length and
* is defined as the square root of the sum of the squares of all vector components.
* @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a>
* @return L<sub>2</sub> norm for the vector
*/
double norm();
/** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm)
* for the vector. This is equal to the sum of the squares of all vector components.
* @see #norm()
* @return square of the L<sub>2</sub> norm for the vector
*/
double normSq();
/** Returns a vector with the same direction but with the given
* norm. This is equivalent to calling {@code vec.normalize().scalarMultiply(mag)}
* but without the intermediate vector.
* @param norm The vector norm
* @return a vector with the same direction as the current instance but the given norm
*/
V withNorm(double norm);
/** Add a vector to the instance.
* @param v vector to add
* @return a new vector
*/
V add(V v);
/** Add a scaled vector to the instance.
* @param factor scale factor to apply to v before adding it
* @param v vector to add
* @return a new vector
*/
V add(double factor, V v);
/** Subtract a vector from the instance.
* @param v vector to subtract
* @return a new vector
*/
V subtract(V v);
/** Subtract a scaled vector from the instance.
* @param factor scale factor to apply to v before subtracting it
* @param v vector to subtract
* @return a new vector
*/
V subtract(double factor, V v);
/** Get the negation of the instance.
* @return a new vector which is the negation of the instance
*/
V negate();
/** Get a normalized vector aligned with the instance. The returned
* vector has a magnitude of 1.
* @return a new normalized vector
* @throws IllegalNormException if the norm is zero, NaN, or infinite
*/
V normalize() throws IllegalNormException;
/** Multiply the instance by a scalar.
* @param a scalar
* @return a new vector
*/
V multiply(double a);
/** Compute the distance between the instance and another vector.
* @param v second vector
* @return the distance between the instance and v
*/
double distance(V v);
/** Compute the square of the distance between the instance and another vector.
* <p>Calling this method is equivalent to calling:
* <code>q.subtract(p).getNormSq()</code> except that no intermediate
* vector is built</p>
* @see #normSq()
* @param v second vector
* @return the square of the distance between the instance and p
*/
double distanceSq(V v);
/** Compute the dot-product of the instance and another vector.
* @param v second vector
* @return the dot product (this &middot; v)
*/
double dot(V v);
/** Compute the angular separation between two vectors in radians.
* @param v other vector
* @return angular separation between this instance and v in radians
* @throws IllegalNormException if either vector has a zero, NaN, or infinite norm
*/
double angle(V v) throws IllegalNormException;
}