1

I have points of line as

line1 = (13.010815620422363, 6.765378475189209), (-9.916780471801758, 12.464008331298828)
line2 = (-28.914321899414062, 2.4057865142822266),(13.973191261291504, -8.306382179260254)

Is there is a way to get the line direction from some formula or code(python)?

Community
  • 1
  • 1
L Lawliet
  • 419
  • 1
  • 7
  • 20
  • What exactly are you asking? ?Now i see that both `line1` and `line2` are tuples, or list of tuples representing coordinates. What do you need to do? – LimorAbv Jun 04 '21 at 14:13
  • @LimorAbv basically line one and line two are 2 lanes on a road which are traveling in opposite direction, I want to know if its in opposite direction or not programmatically – L Lawliet Jun 04 '21 at 14:18
  • See this question: https://stackoverflow.com/questions/18424228/cosine-similarity-between-2-number-lists – Stef Jun 04 '21 at 14:45

2 Answers2

3

First calculate the vectors of the two lines. Then you can calculate the cosine of the angle between the two vectors using the dot product. If the result is close to 1, both lines point in the same direction. If the result is close to -1, the second line points in the opposite direction.

import math

line1 = (13.010815620422363, 6.765378475189209), (-9.916780471801758, 12.464008331298828)
line2 = (-28.914321899414062, 2.4057865142822266),(13.973191261291504, -8.306382179260254)

vec1 = (line1[1][0] - line1[0][0], line1[1][1] - line1[0][1])
vec2 = (line2[1][0] - line2[0][0], line2[1][1] - line2[0][1])

cos_angle = (vec1[0] * vec2[0] + vec1[1] * vec2[1]) / math.sqrt((vec1[0]**2 + vec1[1]**2) * (vec2[0]**2 + vec2[1]**2))

In this case the result is -0.9999993352122917

Remco646
  • 132
  • 2
  • 7
3

Each of your two "lines" have a start point and an end point. This defines a vector, whose coordinates you can get by subtracting the coordinates of the start point from the coordinates of the end point.

To figure out whether two vectors are going in the same direction, you can look at the oriented angle between them; or better yet, at the cosine of that angle. The cosine will be +1 if they are exactly pointing in the same direction; 0 if they are exactly orthogonal; and -1 if they are pointing in exactly opposing direction. Some intermediary value between -1 and +1 if it's not exact.

See also:

With all that in mind:

def vector_of_segment(start, end):
  a, b = start
  c, d = end
  return (c - a, d - b)

def scalar_product(u, v):
  a, b = u
  c, d = v
  return a * c + b * d

import math
def norm(u):
  return math.sqrt(scalar_product(u,u))

# python>=3.8: use math.hypot instead of defining your own norm

def cosine_similarity(u,v):
  return scalar_product(u,v) / (norm(u) * norm(v))

def cosine_similarity_of_roads(line1, line2):
  u = vector_of_segment(*line1)
  v = vector_of_segment(*line2)
  return cosine_similarity(u, v)

If you have one of the two awesome libraries numpy and scipy installed, you can also use already-implemented versions of the cosine similarity from these libraries, rather than implementing your own. Refer to the answers to the question I linked above.

Test:

>>> line1 = (13.010815620422363, 6.765378475189209), (-9.916780471801758, 12.464008331298828)
>>> line2 = (-28.914321899414062, 2.4057865142822266),(13.973191261291504, -8.306382179260254)
>>> cosine_similarity_of_roads(line1, line2)
-0.9999993352122917

Your lines are exactly in opposing directions.

Stef
  • 13,242
  • 2
  • 17
  • 28