001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.geometry.core; 018 019/** Interface representing a vector in a vector space or displacement vectors 020 * in an affine space. 021 * 022 * <p>This interface uses self-referencing generic parameters to ensure 023 * that implementations are only used with instances of their own type. 024 * This removes the need for casting inside of methods in order to access 025 * implementation-specific data, such as coordinate values. 026 * </p> 027 * 028 * @see <a href="https://en.wikipedia.org/wiki/Vector_space">Vector space</a> 029 * @see <a href="https://en.wikipedia.org/wiki/Affine_space">Affine space</a> 030 * 031 * @param <V> Vector implementation type 032 */ 033public interface Vector<V extends Vector<V>> extends Spatial { 034 035 /** Get the zero (null) vector of the space. 036 * @return zero vector of the space 037 */ 038 V getZero(); 039 040 /** Get the L<sub>2</sub> norm (commonly known as the Euclidean norm) for the vector. 041 * This corresponds to the common notion of vector magnitude or length and 042 * is defined as the square root of the sum of the squares of all vector components. 043 * @see <a href="http://mathworld.wolfram.com/L2-Norm.html">L2 Norm</a> 044 * @return L<sub>2</sub> norm for the vector 045 */ 046 double norm(); 047 048 /** Get the square of the L<sub>2</sub> norm (also known as the Euclidean norm) 049 * for the vector. This is equal to the sum of the squares of all vector components. 050 * @see #norm() 051 * @return square of the L<sub>2</sub> norm for the vector 052 */ 053 double normSq(); 054 055 /** Returns a vector with the same direction but with the given 056 * norm. This is equivalent to calling {@code vec.normalize().scalarMultiply(mag)} 057 * but without the intermediate vector. 058 * @param norm The vector norm 059 * @return a vector with the same direction as the current instance but the given norm 060 */ 061 V withNorm(double norm); 062 063 /** Add a vector to the instance. 064 * @param v vector to add 065 * @return a new vector 066 */ 067 V add(V v); 068 069 /** Add a scaled vector to the instance. 070 * @param factor scale factor to apply to v before adding it 071 * @param v vector to add 072 * @return a new vector 073 */ 074 V add(double factor, V v); 075 076 /** Subtract a vector from the instance. 077 * @param v vector to subtract 078 * @return a new vector 079 */ 080 V subtract(V v); 081 082 /** Subtract a scaled vector from the instance. 083 * @param factor scale factor to apply to v before subtracting it 084 * @param v vector to subtract 085 * @return a new vector 086 */ 087 V subtract(double factor, V v); 088 089 /** Get the negation of the instance. 090 * @return a new vector which is the negation of the instance 091 */ 092 V negate(); 093 094 /** Get a normalized vector aligned with the instance. The returned 095 * vector has a magnitude of 1. 096 * @return normalized vector 097 * @throws IllegalArgumentException if the norm is zero, NaN, or infinite 098 * @see #normalizeOrNull() 099 */ 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}