Vector2

geometrycentral::Vector2 is the basic 2D vector type in geometry central. Like a good turkey sandwich, it aims to be unsurprising yet satisfying.

Of particular interest, Vector2 is also used to encode 2D rotations, by supporting multiplication as a complex number. See the rotations section.

#include "geometrycentral/vector2.h"

Construction

Vector2 is a POD type, so you should use brace-initialization sytax:

#include "geometrycentral/vector2.h
using namespace geometrycentral;

Vector2 myVec{3.8, 2.9}; //create
myVec = Vector2{1.1, 2.2}; // reassign

Factory methods can construct a few common values:

static Vector2 Vector2::zero()

Returns the zero vector

static Vector2 Vector2::constant(double c)

Returns a vector with all components set to c

static Vector2 Vector2::infinity()

Returns the infinite vector (\infty, \infty).

static Vector2 Vector2::undefined()

Returns the undefined vector (NaN, NaN).

And serve as constructors:

static Vector2 Vector2::fromAngle(double theta)

Returns the vector (\cos(\theta), \sin(\theta)).

static Vector2 Vector2::fromComplex(std::complex<double> c)

Converts a std::complex<double> to a Vector2.

Access

The two elements of the vector can be accessed as vec.x and vec.y.

Alternately, the two elements can be indexed as vec[0] and vec[1].

Conversion

Vector2::operator std::complex<double>()

Vector2 is implicitly convertible to std::complex<double>.

Vector2::operator<<()

Vector2 can be serialized.

Vector2 v{1.2, 3.4};
std::cout << v << std::endl;
// prints something like: <1.2, 3.4>

Arithmetic

Vector2 supports the element-wise addition, subraction, and scalar multiplication you would probably expect.

Rotations and complex multiplication

Our Vector2 types further obey the multiplication and division rules of complex arithmetic, and thus can be used to represent rotations. For instance, a unit 2D vector representing a rotation can be used to rotate another vector like:

Vector2 v = /* your vector */
Vector2 r = Vector2::fromAngle(PI/4); // rotation by 45 degrees
Vector2 vRot = r * v;
This is fundamentally no different from using 2x2 rotation matrices, but leads to much cleaner code (try using division to compute relative rotations!).

Member operations

These methods do not change the underlying Vector2, but return a new Vector2.

Vector2 vec{1., 2.};
vec.rotate90();         // does nothing
vec = vec.rotate90();   // much better

Vector2 Vector2::normalize()

Returns a unit-norm vector with the same direction. If the input is the zero vector, the result will contain NaNs.

Vector2 Vector2::rotate(double theta)

Rotate the vector by angle \theta in the counter-clockwise direction.

Vector2 Vector2::rotate90()

Rotate the vector by 90^{\circ} in the counter-clockwise direction.

Vector2 Vector2::pow(double p)

Raise the vector to a real power, in the sense of complex arithmetic. (see std::pow)

Vector2 Vector2::pow(Vector2 p)

Raise the vector to a complex power, in the sense of complex arithmetic. (see std::pow)

Vector2 Vector2::conj()

Transform the vector to its complex conjugate, negating the y component.

Vector2 Vector2::inv()

Invert the vector, in the sense of complex arithmetic. Equivalent to Vector2{1., 0.} / v.

Function operations

These operations do not change the vector on which they are called.

double norm(Vector2 v)

Returns the magnitude of the vector.

Also available as v.norm().

double norm2(Vector2 v)

Returns the squared magnitude of the vector.

Also available as v.norm().

Vector2 unit(Vector2 v)

Returns normalized copy of the vector.

double arg(Vector2 v)

Returns the argument in the sense of complex arithmetic (i.e., the angle against the x-axis).

Also available as v.arg().

double dot(Vector2 u, Vector2 v)

Returns the dot product between two vectors.

double cross(Vector2 u, Vector2 v)

Returns the “cross” product between two vectors, that is u.x * v.y - u.y * v.x. Intuitively, the z-component of the 3D cross product of vectors in the plane.

Vector3 cross3(Vector2 u, Vector2 v)

Returns the 3D cross product of vectors in the plane.

double angle(Vector2 u, Vector2 v)

Returns the angle between two not-necessarily-unit vectors. Output in the range [0, \pi].

Vector2 clamp(Vector2 val, Vector2 low, Vector2 high)

Returns returns a a vector where each component has been clamped to be between the corresponding compnents of low and high.

Vector2 componentwiseMin(Vector2 u, Vector2 v)

Returns a new vector, each component of which is the minimum of that component in u and v.

Vector2 componentwiseMax(Vector2 u, Vector2 v)

Returns a new vector, each component of which is the maximum of that component in u and v.

Properties

bool isfinite(Vector2 u)

Returns true if both of the components of the vector are finite.

Note: this function is intentionally not camel-cased out of solidarity with std::isfinite().

Also available as u.isFinite().

bool isDefined(Vector2 u)

Returns true if both of the components of the vector are not NaN.

Also available as u.isDefined().