Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python code to calculate angle between three points (lat long coordinates)

Can anybody suggest how to calculate angle between three points (lat long coordinates)

A : (12.92473, 77.6183)
B : (12.92512, 77.61923)
C : (12.92541, 77.61985)
like image 215
itsvks Avatar asked Mar 03 '17 16:03

itsvks


People also ask

How do you find an angle in Python?

angle() function is used when we want to compute the angle of the complex argument. A complex number is represented by “ x + yi ” where x and y are real number and i= (-1)^1/2 . The angle is calculated by the formula tan-1(x/y).


1 Answers

I see two main ways to solve your problem, assuming you want angle ABC (B is the vertex of the angle). Since your three points are close to each other (less than 0.0007° latitude and 0.002° longitude apart), we can approximate the earth as a plane and use two-dimensional vector calculations. A degree of longitude and of latitude are not the same distance when we are away from the equator, but we can adjust for that. Another solution is to treat your points as in three-dimensional space and use three-dimensional vector calculations. Here we just need to convert the given spherical coordinates to 3D Cartesian coordinates.

Here is my code for your problem. I use the numpy module here for convenience, but this can be done pretty easily without it. This code is fairly wordy so you can see better just what is being done.

import numpy as np
import math

def latlong_to_3d(latr, lonr):
    """Convert a point given latitude and longitude in radians to
    3-dimensional space, assuming a sphere radius of one."""
    return np.array((
        math.cos(latr) * math.cos(lonr),
        math.cos(latr) * math.sin(lonr),
        math.sin(latr)
    ))

def angle_between_vectors_degrees(u, v):
    """Return the angle between two vectors in any dimension space,
    in degrees."""
    return np.degrees(
        math.acos(np.dot(u, v) / (np.linalg.norm(u) * np.linalg.norm(v))))

# The points in tuple latitude/longitude degrees space
A = (12.92473, 77.6183)
B = (12.92512, 77.61923)
C = (12.92541, 77.61985)

# Convert the points to numpy latitude/longitude radians space
a = np.radians(np.array(A))
b = np.radians(np.array(B))
c = np.radians(np.array(C))

# Vectors in latitude/longitude space
avec = a - b
cvec = c - b

# Adjust vectors for changed longitude scale at given latitude into 2D space
lat = b[0]
avec[1] *= math.cos(lat)
cvec[1] *= math.cos(lat)

# Find the angle between the vectors in 2D space
angle2deg = angle_between_vectors_degrees(avec, cvec)


# The points in 3D space
a3 = latlong_to_3d(*a)
b3 = latlong_to_3d(*b)
c3 = latlong_to_3d(*c)

# Vectors in 3D space
a3vec = a3 - b3
c3vec = c3 - b3

# Find the angle between the vectors in 2D space
angle3deg = angle_between_vectors_degrees(a3vec, c3vec)


# Print the results
print('\nThe angle ABC in 2D space in degrees:', angle2deg)
print('\nThe angle ABC in 3D space in degrees:', angle3deg)

This gives the results

The angle ABC in 2D space in degrees: 177.64369006

The angle ABC in 3D space in degrees: 177.643487338

Note that the results are very close (off by about one five-thousandth of a degree), as expected for three points so close together.

like image 186
Rory Daulton Avatar answered Oct 22 '22 20:10

Rory Daulton