Calculating the angle between Points

Use Dot product:

v1.v2 = v1.x * v2.x + v1.y * v2.y

v1.v2 = |v1| * |v2| * cos(theta)
---------------------------------+
                                 |
                                 +-->  theta = acos(v1.v2 / |v1|*|v2|)

A sample code is:

float angleBetween(const Point &v1, const Point &v2)
{
    float len1 = sqrt(v1.x * v1.x + v1.y * v1.y);
    float len2 = sqrt(v2.x * v2.x + v2.y * v2.y);

    float dot = v1.x * v2.x + v1.y * v2.y;

    float a = dot / (len1 * len2);

    if (a >= 1.0)
        return 0.0;
    else if (a <= -1.0)
        return PI;
    else
        return acos(a); // 0..PI
}

It calculates angle between v1 and v2 as below image

enter image description here


Assuming you want to calculate the angle between the two points relative to the origin of the 2D plane, you can use the dot product to calculate the angle between the points (like how the other answer of this question described).

OpenCV has implementations of calculating the dot product and the length of points. The dot product of two points is:

v1.dot(v2) // v1.x * v2.x + v1.y * v2.y

Length of vector (commonly referred as the L2 Norm of vector) using cv::norm is:

cv::norm(v1) // sqrt(v1.x * v1.x + v1.y * v1.y)

Using OpenCV's implementations of dot product and the length of vector we have the following sample code

double angle(const Point& v1, const Point& v2)
{
    double cosAngle = v1.dot(v2) / (cv::norm(v1) * cv::norm(v2));
    if (cosAngle > 1.0)
        return 0.0;
    else if (cosAngle < -1.0)
        return CV_PI;
    return std::acos(cosAngle);
}

This solution isn't only limited to 2D points. It can be used for calculating the angle between 3D points as well.

Note that angle is in Radians.

If you want degrees, you should multiply it by 180 / Pi:

return std::acos(cosAngle) * 180 / CV_PI

Tags:

C++

Opencv