简体   繁体   中英

Minimum, mean and maximum distance between points 3-D in Python

I have a list of x,y,z points. Using the formula to find the distance between two points in 3-D

import math
import numpy as np

point0 = x0, y0, z0
point1 = x1, y1, z1

dist = math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2)

def dist3d((x0, y0, z0), (x1, y1, z1)):
    return math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2)

i wish to write a optimized loop and store the distance

points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)]

dist01 = dist3d(test[0],test[1])
dist02 = dist3d(test[0],test[2])
dist03 = dist3d(test[0],test[2])
dist04 = dist3d(test[0],test[2])

dist12 = dist3d(test[1],test[2])
dist13 = dist3d(test[1],test[3])

dist23 = dist3d(test[2],test[3])

3d_l=[(dist01),(dist02),(dist03),(dist04),(dist12),(dist13),(dist23)]

3d_max =max(3d_l)
3d_min = min(3d_l)
3d_mean =  np.average(3d_l)

I wrote the following function (it's not optimized)

def dist3d((x0, y0, z0), (x1, y1, z1)):
    return math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2)

def dist_3d(obs):
    dist_list = list()
    while len(obs) != 1:
        obs_g = [(obs[0], x) for x in obs[1:]]
        dist_list.append([dist3d(obs_g[i][0], obs_g[i][1]) for i in xrange(len(obs_g))])
        obs.pop(0)
    return dist_list

points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)]
print dist_3d(points)
[[4.217700795331081, 5.922339064664832, 3.554222840244929], [2.1374049685457694, 7.046453008421205], [8.107835716151763]]

If you don't mind using scipy, this is fairly trivial:

import numpy as np
import scipy.spatial.distance as distance 

points = np.array([(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)])

dist = distance.pdist(points)
print dist.max()
print dist.min()
print np.median(dist)
print np.average(dist)

Here's a generalized version that uses built-in and module functions as much as possible. I don't have numpy installed, but if it has a 3-D, or nD, distance function in it, use that instead of dist3D() below.

Actually, numpy contains several (other) functions that could be used to speed up some of these immediate calculations. If you're looking for more of an answer based on it, you should indicate this by at least modifying your question's tags.

import math
import numpy as np

points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0),
          (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)]
points += [points[0]]  # dup first point to include dist from last to first
dist3D = lambda a, b: math.sqrt((a[0]-b[0])**2 + (a[1]-b[1])**2 + (a[2]-b[2])**2)
dists = sorted(dist3D(points[i], points[i+1]) for i in xrange(len(points)-1))
min_dist, max_dist = dists[0], dists[-1]
#mean_dist = sum(dists) / len(dists)
mean_dist = np.average(dists)

print 'min_dist: {:.2f}, mean_dist: {:.2f}, max_dist: {:.2f}'.format(
    min_dist, mean_dist, max_dist)

math.sqrt is a relatively heavy operation. You can store squares of distances instead, which is enough for finding the minimum, median and maximum, and then get square roots. Further, try finding max and min with a single iteration manually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM