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.core; 18 19 /** Interface representing a vector in a vector space or displacement vectors 20 * in an affine space. 21 * 22 * <p>This interface uses self-referencing generic parameters to ensure 23 * that implementations are only used with instances of their own type. 24 * This removes the need for casting inside of methods in order to access 25 * implementation-specific data, such as coordinate values. 26 * </p> 27 * 28 * @see <a href="https://en.wikipedia.org/wiki/Vector_space">Vector space</a> 29 * @see <a href="https://en.wikipedia.org/wiki/Affine_space">Affine space</a> 30 * 31 * @param <V> Vector implementation type 32 */ 33 public interface Vector<V extends Vector<V>> extends Spatial { 34 35 /** Get the zero (null) vector of the space. 36 * @return zero vector of the space 37 */ 38 V getZero(); 39 40 /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector. 41 * This corresponds to the common notion of vector magnitude or length and 42 * is defined as the square root of the sum of the squares of all vector components. 43 * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a> 44 * @return L<sub>2</sub> norm for the vector 45 */ 46 double norm(); 47 48 /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm) 49 * for the vector. This is equal to the sum of the squares of all vector components. 50 * @see #norm() 51 * @return square of the L<sub>2</sub> norm for the vector 52 */ 53 double normSq(); 54 55 /** Returns a vector with the same direction but with the given 56 * norm. This is equivalent to calling {@code vec.normalize().scalarMultiply(mag)} 57 * but without the intermediate vector. 58 * @param norm The vector norm 59 * @return a vector with the same direction as the current instance but the given norm 60 */ 61 V withNorm(double norm); 62 63 /** Add a vector to the instance. 64 * @param v vector to add 65 * @return a new vector 66 */ 67 V add(V v); 68 69 /** Add a scaled vector to the instance. 70 * @param factor scale factor to apply to v before adding it 71 * @param v vector to add 72 * @return a new vector 73 */ 74 V add(double factor, V v); 75 76 /** Subtract a vector from the instance. 77 * @param v vector to subtract 78 * @return a new vector 79 */ 80 V subtract(V v); 81 82 /** Subtract a scaled vector from the instance. 83 * @param factor scale factor to apply to v before subtracting it 84 * @param v vector to subtract 85 * @return a new vector 86 */ 87 V subtract(double factor, V v); 88 89 /** Get the negation of the instance. 90 * @return a new vector which is the negation of the instance 91 */ 92 V negate(); 93 94 /** Get a normalized vector aligned with the instance. The returned 95 * vector has a magnitude of 1. 96 * @return normalized vector 97 * @throws IllegalArgumentException if the norm is zero, NaN, or infinite 98 * @see #normalizeOrNull() 99 */ 100 V normalize(); 101 102 /** Attempt to compute a normalized vector aligned with the instance, returning null if 103 * such a vector cannot be computed. This method is equivalent to {@link #normalize()} 104 * but returns null instead of throwing an exception on failure. 105 * @return normalized vector or null if such a vector cannot be computed, i.e. if the 106 * norm is zero, NaN, or infinite 107 * @see #normalize() 108 */ 109 V normalizeOrNull(); 110 111 /** Multiply the instance by a scalar. 112 * @param a scalar 113 * @return a new vector 114 */ 115 V multiply(double a); 116 117 /** Compute the distance between the instance and another vector. 118 * @param v second vector 119 * @return the distance between the instance and v 120 */ 121 double distance(V v); 122 123 /** Compute the square of the distance between the instance and another vector. 124 * <p>Calling this method is equivalent to calling: 125 * <code>q.subtract(p).getNormSq()</code> except that no intermediate 126 * vector is built</p> 127 * @see #normSq() 128 * @param v second vector 129 * @return the square of the distance between the instance and p 130 */ 131 double distanceSq(V v); 132 133 /** Compute the dot-product of the instance and another vector. 134 * @param v second vector 135 * @return the dot product (this · v) 136 */ 137 double dot(V v); 138 139 /** Compute the angular separation between two vectors in radians. 140 * @param v other vector 141 * @return angular separation between this instance and v in radians 142 * @throws IllegalArgumentException if either vector has a zero, NaN, or infinite norm 143 */ 144 double angle(V v); 145 }