1
$\begingroup$

I have two numpy lists with 3D coordinates of vertecies of two meshes. These lists are of unequal length. I would like to calculate the 3D distance between every coordinate in arrayA and arrayB.

arrayA([[X1 ,  Y1 , Z1],
       [X2 ,  Y2 ,  Z2],
       [X3 ,  Y3 ,  Z3]])
       ...


arrayB([[X1 , Y1 ,  Z1],
       [X2 ,  Y2 ,  Z2],
       [X3 ,  Y3 ,  Z3],
       [X4 ,  Y4 ,  Z4]])
       ...

While searching I found this post about getting a single 3D coordinate pair distance but I am not sure how I can use it as my numpy arrays are of unequal lengths.

I would like to generate a numpy array with all the lengths. This means distances of All 3D coordinates from ArrayA with the first, second, third... (and so on) 3D coordinate of ArrayB.

---EDIT---

I feel like I have been able to make some progress but I think that something is still not right. I am experimenting with a subset of all the coordinates ant took the first 3 vertices from the two meshes. So ArrayA (vertex_array[0]) has 3 XYZ coordinates and ArrayB (vertex_array[1]) has 3 XYZ coordinates. I am expecting to get 9 output entries but it outputs 12. I have also put in a couple of print statements but I can't seem to figure it out.

import numpy as np
...
iterate = 0
iterate2 = 0
...
for entries in vertex_array[1]:
    for vertex in vertex_array[0]:
        p1 = vertex
        p2 = vertex_array[1][0]
        iterate = iterate+1
        squared_dist = np.sum((p1-p2)**2, axis=0)
        dist = np.sqrt(squared_dist)
        print(dist)
        print("loop 1: " + str(iterate))
        
    p3 = vertex_array[0][0]
    p4 = entries
    iterate2 = iterate2 + 1
    squared_dist2 = np.sum((p3-p4)**2, axis=0)
    dist2 = np.sqrt(squared_dist2)
    print(dist2)
    print("loop 2: " + str(iterate2))

Output:

3.677461821966065
loop 1: 1
3.36723045259329
loop 1: 2
3.7110807813512268
loop 1: 3
3.677461821966065
loop 2: 1
3.677461821966065
loop 1: 4
3.36723045259329
loop 1: 5
3.7110807813512268
loop 1: 6
4.029668579506317
loop 2: 2
3.677461821966065
loop 1: 7
3.36723045259329
loop 1: 8
3.7110807813512268
loop 1: 9
3.7166097270669267
loop 2: 3
$\endgroup$

1 Answer 1

0
$\begingroup$

You can calculate this purely using Numpy, using the numpy linalg.norm (Euclidean distance) fucntion:

distances = np.array([ np.linalg.norm(B - p, axis=1) for p in A])

We're making use here of Numpy's matrix operations to calculate the distance for between each point in B and each point in A.

For the following two arrays, this will be the result (using 2D arrays for simplicity, but it will work exactly the same for 3D arrays):

A = np.array([[0.16869694, 0.18218867],
       [0.13406977, 0.92704429],
       [0.42916002, 0.70700565],
       [0.31897904, 0.74722291],
       [0.95014724, 0.37253304],
       [0.25335466, 0.46849091],
       [0.15266878, 0.69878319],
       [0.81076298, 0.46946201],
       [0.03145542, 0.62978006],
       [0.63422485, 0.37211463]])

B = np.array([[0.82858205, 0.88478606],
       [0.11420783, 0.21636374],
       [0.48167179, 0.68689633],
       [0.09455677, 0.25089711],
       [0.73376651, 0.05755397]])

distances = np.array([ np.linalg.norm(B - p, axis=1) for p in A])
print(distances)

# Result:

array([[0.9638939 , 0.06431951, 0.59387127, 0.10108223, 0.57865139],
       [0.69579671, 0.71095805, 0.42249049, 0.67730073, 1.05624316],
       [0.43719998, 0.58303034, 0.05623051, 0.56568042, 0.71733716],
       [0.52784359, 0.56898392, 0.17351723, 0.54470602, 0.80479308],
       [0.52648006, 0.85040199, 0.56417508, 0.86419347, 0.3821419 ],
       [0.71006211, 0.28797561, 0.31595829, 0.26937675, 0.63219042],
       [0.7010391 , 0.48395018, 0.32921768, 0.45164028, 0.8653609 ],
       [0.41570613, 0.74111256, 0.39443465, 0.7488137 , 0.4190426 ],
       [0.83692229, 0.42161715, 0.45382491, 0.38410164, 0.90591588],
       [0.54827613, 0.54284072, 0.34979988, 0.55311421, 0.32993477]])
$\endgroup$
2
  • $\begingroup$ How do I rearrange the order that the distances are displayed in? I notice that the first distance value is distances[0][0]. The second distance value is distances[1][0]. Third value is distances[2][0]. This is not very intuitive to me. I'd prefer to have them coming one after the other so that I can easily find the index of a particular distance measurement. $\endgroup$
    – TheAliw1
    Aug 11, 2022 at 16:57
  • $\begingroup$ You can rearrange the original arrays to change the order of the final results, or run (A - p, axis=1) for p in B in the norm function, to get [0][0], then [0][1], if I'm not mistaken $\endgroup$
    – TLousky
    Aug 12, 2022 at 6:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .