Total length of a trajectory

807 views Asked by At

I have a matrix containing 2 columns which correspond to the coordinates (x,y) of points in a trajectory. I want to calculate the total length of the trajectory using euclidean distance.

First I open my trajectory file

fichier="fichier_position_2_test.txt"
file = open(fichier, "rb")
for ligne in file:
    ligne = ligne.split(' ')
    m.append(array([(ligne[1]),(ligne[2])]))

Then I calculate the euclidean distance between two points in the matrix

def T(mat):
    n=len(mat)
    M=[0 for x in range(mat)]
    for j in range(0,n-1):
        val = sqrt((mat[j+1][0]-mat[j][0])*(mat[j+1][0]-mat[j][0]) + (mat[j+1][1]-mat[j][1])*(mat[j+1][1]-mat[j][1]))
        M.append(val)
        L = sum(M)
    return L

However it doesn't work so well

Here is my file http://s000.tinyupload.com/?file_id=26745790747175243934

Here are some test

#TEST
A = array([(-4e-9,7.2e-6),(-5.7e-4,3.7e-4),(-8.7e-3,5.7e-3),(-1.2e-3,7.1e-4)])
print T(A)
print T(m)

And the result

0.0194054064971
Traceback (most recent call last):
File "tortuosity.py", line 46, in <module>
print T(m)
File "tortuosity.py", line 37, in T
val = sqrt((mat[j+1][0]-mat[j][0])*(mat[j+1][0]-mat[j][0]) + (mat[j+1][1]-mat[j][1])*(mat[j+1][1]-mat[j][1]))
TypeError: unsupported operand type(s) for -: 'numpy.string_' and 'numpy.string_'

I think the problem comes from the matrix m. Because, see that with the matrix A (an example) it gives the expected result (0.0194054064971)

1

There are 1 answers

0
tobias_k On

The problem seems to be that you are never converting the strings from the file to floating point numbers. Thus your array contains a lot of strings (that look like numbers, but are still strings), and you can not take the difference of strings.

The minimum to make your code work is to change this line to:

m.append(array([float(ligne[1]), float(ligne[2])]))

But note that there are some other, minor issues:

  • you are initializing your list of distances with 0, but then you append to those existing zeros, instead of overwriting them
  • in fact, you do not need that list at all, just calculate the sum directly
  • you can make your code much simpler by using the power operator ** instead of repeating the same expression twice
  • you can use zip(list, list[1:]) to iterate pairs of consecutive lines
  • use tuple unpacking instead of indexing to make the code more readable
  • use with to open files, and do not use file as a variable name, as it's shadowing the type

All in all, you could make your code quite a bit more compact:

def T(mat):
    return sum( sqrt((y2-y1)**2 + (x2-x1)**2) for (x1, y1), (x2, y2) in zip(mat, mat[1:]))

with open("fichier_position_2_test.txt") as f:
    m = np.array([(float(items[1]), float(items[2])) for items in (line.split() for line in f)])
    print T(m)

Result for m is 0.00132038721131, and for A is 0.0194054064971, as expected.