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 }