HOWTO · C++
How to Calculate Angle Between Two Vectors in C++
Calculate the principal angle between equal-dimension vectors in C++ with built-in arrays or std::array. Learn the dot product formula, radians and degrees, and how to handle zero vectors and signed angles.
On this page
Use the dot product to calculate the principal angle between two equal-dimension vectors. For vectors u and v, the formula is theta = acos((u · v) / (|u| * |v|)). In C++, compute the dot product and each magnitude, clamp the cosine value to [-1, 1] to account for floating-point rounding, and pass it to std::acos. The result is in radians; multiply by 180 / pi when you need degrees.
Understand the dot product and angle formula
A vector is an ordered set of components, such as (x, y) or (x, y, z). Its magnitude is its length, calculated as the square root of the sum of its squared components. The dot product of two vectors is the sum of the products of corresponding components. For example, u · v is u[0] * v[0] + u[1] * v[1] + ....
The cosine of the angle is the dot product divided by the product of the two magnitudes. Applying inverse cosine (acos) gives the unsigned principal angle from 0 to 180 degrees (or 0 to pi radians). This formula works in 2D, 3D, and higher dimensions as long as both vectors have the same number of components. It does not return an orientation such as clockwise versus counterclockwise.
Calculate the angle with a C++ array
This complete example uses two built-in arrays with the same declared length. The function returns false if either magnitude is zero, since an angle with a zero vector is undefined. Otherwise, it computes the cosine, clamps it to its valid mathematical range, and prints the result in degrees.
Run this example:
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
bool calculateAngleDegrees(const double u[], const double v[], int size,
double& angleDegrees) {
double dot = 0.0;
double squaredU = 0.0;
double squaredV = 0.0;
for (int i = 0; i < size; ++i) {
dot += u[i] * v[i];
squaredU += u[i] * u[i];
squaredV += v[i] * v[i];
}
if (squaredU == 0.0 || squaredV == 0.0) {
return false;
}
double cosine = dot / std::sqrt(squaredU * squaredV);
cosine = std::max(-1.0, std::min(1.0, cosine));
const double pi = std::acos(-1.0);
angleDegrees = std::acos(cosine) * 180.0 / pi;
return true;
}
int main() {
const int size = 3;
const double u[size] = {1.0, 0.0, 0.0};
const double v[size] = {0.0, 1.0, 0.0};
double angleDegrees = 0.0;
if (calculateAngleDegrees(u, v, size, angleDegrees)) {
std::cout << std::fixed << std::setprecision(1)
<< "Angle: " << angleDegrees << " degrees\n";
} else {
std::cout << "An angle requires two nonzero vectors.\n";
}
}
The two sample vectors are perpendicular, so the calculated angle is 90 degrees.
Calculate the angle with std::array
std::array represents a fixed-size sequence and carries its element count in its type. This version uses C++11 or later and infers the count from the array type, so both inputs have the same number of components. The calculation and zero-vector handling are the same as in the built-in-array version.
#include <algorithm>
#include <array>
#include <cmath>
#include <iomanip>
#include <iostream>
bool calculateAngleDegrees(const std::array<double, 3>& u,
const std::array<double, 3>& v,
double& angleDegrees) {
double dot = 0.0;
double squaredU = 0.0;
double squaredV = 0.0;
for (std::size_t i = 0; i < u.size(); ++i) {
dot += u[i] * v[i];
squaredU += u[i] * u[i];
squaredV += v[i] * v[i];
}
if (squaredU == 0.0 || squaredV == 0.0) {
return false;
}
double cosine = dot / std::sqrt(squaredU * squaredV);
cosine = std::max(-1.0, std::min(1.0, cosine));
const double pi = std::acos(-1.0);
angleDegrees = std::acos(cosine) * 180.0 / pi;
return true;
}
int main() {
const std::array<double, 3> u = {1.0, 0.0, 0.0};
const std::array<double, 3> v = {0.0, 1.0, 0.0};
double angleDegrees = 0.0;
if (calculateAngleDegrees(u, v, angleDegrees)) {
std::cout << std::fixed << std::setprecision(1)
<< "Angle: " << angleDegrees << " degrees\n";
} else {
std::cout << "An angle requires two nonzero vectors.\n";
}
}
Use std::array<double, N> when the dimension is fixed and known at compile time. It does not make the calculation inherently more efficient; its main benefit here is that the size is part of the type and can be obtained with .size().
Handle zero vectors, dimensions, and signed angles
An angle is undefined if either vector has zero magnitude. Check for this before dividing by the product of magnitudes, as the examples do. For built-in arrays, pass the actual shared length and ensure both arrays contain at least that many elements. With std::array, using the same N in both types enforces equal dimensions.
The dot-product formula gives an unsigned principal angle. In 2D, an oriented angle can be computed with atan2(cross, dot), where the scalar cross product is u.x * v.y - u.y * v.x. In 3D, the signed-angle formula atan2(n · (u × v), u · v) measures the oriented angle in the plane perpendicular to a chosen unit normal n when both vectors lie in that plane. If either vector is outside the intended plane, first project both vectors onto that plane and apply the formula to the projections; it then measures the angle between those projected vectors. The normal defines the positive direction; it is not added to the dot-product formula. These signed-angle methods return radians, which can be converted to degrees with the same factor used above.
Frequently asked questions
What does the dot product tell me? It combines corresponding components into a scalar. Relative to the magnitudes, its value determines the cosine of the angle: positive for an acute principal angle, zero for perpendicular vectors, and negative for an obtuse principal angle.
Does std::acos return degrees? No. It returns radians. Convert radians to degrees by multiplying by 180 / pi; alternatively, keep radians if that is what the rest of your program uses.
Can the vectors have different dimensions? No. A dot product pairs corresponding components, so the vectors must have the same dimension. For built-in arrays, use one correct shared length. std::array makes the size visible in its type.
Can I use the formula in 3D? Yes. The dot product and magnitude formula applies to any equal-dimension vectors, including 3D vectors. Use a signed-angle calculation with a reference normal only when orientation matters.
Should I use a vector-math library? For a small calculation, the examples above are sufficient. A library such as Eigen or GLM can be useful when a project already relies on its vector and matrix types or needs a broader set of operations.