0

I need a function to treat each point as the origin, starting from the one closest to (0,0), then compute the angle and length of each line segment from that point to every other point. It should skip over anything that would create a same line segment already computed before

However, my function is not taking into account the line segment from my first point to second point. Please help... here is the function

import math

def compute_vectors(points):
    vectors = []
    previous = points[0]
    for point in points:
        x = point[0] - previous[0]
        y = point[1] - previous[1]
        angle = math.degrees(math.atan2(y, x))
        if angle < 0:
            angle += 360
        length = math.sqrt(x**2 + y**2)
        vectors.append((angle, length))
        previous = point
    return vectors[1:]
  

points = [[1,1],[2,2],[3,1]] 
compute_vectors(points)

>>> [(45.0, 1.4142135623730951), (315.0, 1.4142135623730951)]

I need it to output

>>> [(45.0, 1.4142135623730951),(0.0, 2),(315.0, 1.4142135623730951)]
  • 2
    Seems like you want to compare all combinations of points. Maybe starting the loop with something like `for p0, p1 in itertools.combinations(points, r=2):` – Mark Jan 18 '23 at 04:01
  • 1
    Does this answer your question? [How to get all possible combinations of a list’s elements?](https://stackoverflow.com/questions/464864/how-to-get-all-possible-combinations-of-a-list-s-elements) – Pranav Hosangadi Jan 18 '23 at 04:13
  • Some unasked-for advice: 1) Check out `math.hypot()`. 2) Consider the value of, for example, `-10 % 360`. (But notice that `%` works differently in Python than in, say, C or Java.) – Ture Pålsson Jan 18 '23 at 11:30

2 Answers2

0

I think you want to used nested for loops to create the pairs that are being compared. Think about a matrix where the values are the cartesian product of the list of indexes of the input list with itself:

00     01 02 03 04 05
10 11     12 13 14 15
20 21 22     24 24 25
30 31 32 33     34 35
40 41 42 43 44     45
50 51 52 53 54 55

I put the diagonal split in there because the optimization you want (only generate values for pairs that have not been considered already) can be achieved by only selecting index pairs that are in the upper half of the matrix (not including the main diagonal).

Something like this might work:

    for idx, pt1 in enumerate(pts):
        for idx2 in range(idx+1, len(pts)):
            pt2 = pts[idx2]
            <do computations with pt1 and pt2>
            .....

Used like this:

>>> l=[(1, 1), (2, 2), (3, 3), (4, 4)]
>>> for idx, val in enumerate(l):
...   for idx2 in range(idx+1, len(l)):
...     val2 = l[idx2]
...     print(f"point 1 = {val}", f"point2 = {val2}")
... 
point 1 = (1, 1) point2 = (2, 2)
point 1 = (1, 1) point2 = (3, 3)
point 1 = (1, 1) point2 = (4, 4)
point 1 = (2, 2) point2 = (3, 3)
point 1 = (2, 2) point2 = (4, 4)
point 1 = (3, 3) point2 = (4, 4)
Z4-tier
  • 7,287
  • 3
  • 26
  • 42
0
import itertools
import math


def compute_angles_and_lengths(points):
  angles_and_lengths = []
  for i in itertools.combinations(points, 2):
    x = i[1][0] - i[0][0] 
    y = i[1][1] - i[0][1]
    lengths = math.sqrt(x**2+y**2)
    angle = math.degrees(math.atan2(y,x))   
    angles_and_lengths.append((angle, lengths))
  return angles_and_lengths


points = [[1,1],[2,2],[3,1]]    
compute_angles_and_lengths(points)

>>> [(45.0, 1.4142135623730951), (0.0, 2.0), (-45.0, 1.4142135623730951)]
  • 1
    Very expressive function-name. Instead of code-only answer, should explain your code, and include link to docs of `itertools.combinations` function as [suggested by mark](https://stackoverflow.com/questions/75154437/finding-all-angles-between-every-sequential-line-segment#comment132622565_75154437). Maybe reference the already answered [question duplicate](https://stackoverflow.com/questions/464864/how-to-get-all-possible-combinations-of-a-list-s-elements). – hc_dev Jan 18 '23 at 12:25