pythongeometryangle

How to calculate the angle from a point to midpoint of a line?


I want to calculate the angle formed by a line segment from p1 to the midpoit of the line connecting p2 and p3, and the line formed by p2 and p3. I used code as below, but the result seems not correct, does anyone help me?

def calculateAngle(point1, point2, point3):
    lon1, lat1 = point1
    lon2, lat2 = point2
    lon3, lat3 = point3
    latCenter = (lat2 + lat3) / 2
    lonCenter = (lon2 + lon3) / 2
    xV1 = latCenter - lat1
    yV1 = lonCenter - lon1
    xV2 = lat3 - lat1
    yV2 = lon3 - lon1
    dotProduct = xV1 * xV2 + yV1 * yV2
    magnitudeV1 = sqrt(xV1 ** 2 + yV1 ** 2)
    magnitudeV2 = sqrt(xV2 ** 2 + yV2 ** 2)

    if magnitudeV1 == 0 or magnitudeV2 == 0:
        return 0
    
    cosTheta = dotProduct / (magnitudeV1 * magnitudeV2)
    cosTheta = max(min(cosTheta, 1), -1)
    theta = acos(cosTheta)
    angleInDegrees = degrees(theta)
    return angleInDegrees, theta

enter image description here


Solution

  • Your V1 and V2 vectors are wrong. You have:

        xV1 = latCenter - lat1
        yV1 = lonCenter - lon1
        xV2 = lat3 - lat1
        yV2 = lon3 - lon1
    

    What you want is:

        xV1 = lon1 - lonCenter
        yV1 = lat1 - latCenter
        xV2 = lon3 - lonCenter
        yV2 = lat3 - latCenter
    
    

    If you look at your diagram, it should be clear. Both vectors run from the midpoint to the points point1 and point3. And longitude is X, latitude is Y. Again, this is correct in the diagram but reversed in the original V1 and V2 assignments.

    Note that you could alternatively use:

        xV1 = lon1 - lonCenter
        yV1 = lat1 - latCenter
        xV2 = lon3 - lon2
        yV2 = lat3 - lat2
    

    This effectively doubles the magnitude of V2, which will cancel out when later dividing by its magnitude.