найдите длину между каждой точкой из массива python

#python #numpy #coordinates

Вопрос:

предположим, у нас есть 8 точек,координаты x, y которых заданы как

 [[[224  64]]
 [[ 62 381]]
 [[224 661]]
 [[568 661]]
 [[733 348]]
 [[650 205]]
 [[509 204]]
 [[509  64]]]
 

Предположим, что это 8 точек многоугольника, и вы хотите найти длину каждой стороны. Для двух точек я могу найти длину, как

 dx = math.abs(x2 - x1)
dy = math.abs(y2 - y1)
dist = math.sqrt((x2 - x1)**2   (y2 - y1)**2)
 

Как найти длину каждой стороны многоугольника с указанными выше x, y координатами?

Комментарии:

1. Эм, вы просто повторяете это вычисление 8 раз, предположительно в цикле. И это не восьмиугольник. Это 5 сторон шестиугольника.

2. да, я сталкиваюсь с трудностями при циклическом использовании только @TimRoberts

Ответ №1:

Допустим, ваш список называется coords . У вас есть numpy тег, поэтому я предполагаю, что вам нужно быстрое решение с использованием numpy.

 coords = [
 [224,  64],
 [ 62, 381],
 [224, 661],
 [568, 661],
 [733, 348],
 [650, 205],
 [509, 204],
 [509,  64]]
 

Вы захотите вызвать np.diff последовательные элементы, поэтому, чтобы получить последнюю сторону, вам нужно будет повторить первую точку в конце. Вы можете сделать это одновременно с преобразованием массива в numpy:

 vertices = np.concatenate((coords, coords[:1]), axis=0)
 

Теперь найдите длину сторон:

 sides = np.linalg.norm(np.diff(vertices, axis=0), axis=-1)
 

Для вашего 2D-случая вы также можете использовать np.hypot вместо np.linalg.norm :

 sides = np.hypot(*np.diff(vertices, axis=0).T)
 

Ответ №2:

 import math
points = [
 [224,  64],
 [ 62, 381],
 [224, 661],
 [568, 661],
 [733, 348],
 [650, 205],
 [509, 204],
 [509,  64]]

for x,y in zip(points,points[1:]):
    d = math.sqrt((x[1]-y[1])*(x[1]-y[1])   (x[0]-y[0])*(x[0]-y[0]))
    print(x, y, d)
 

Выход:

 [224, 64] [62, 381] 355.99578649191903
[62, 381] [224, 661] 323.4872485894923
[224, 661] [568, 661] 344.0
[568, 661] [733, 348] 353.82764165621654
[733, 348] [650, 205] 165.3420696616563
[650, 205] [509, 204] 141.00354605470034
[509, 204] [509, 64] 140.0
 

Вот как это выглядит:
введите описание изображения здесь

ПОСЛЕДУЮЩИЕ ДЕЙСТВИЯ

Вот код, использующий вашу точную структуру:

 import numpy as np
import math
points = [
 [224,  64],
 [ 62, 381],
 [224, 661],
 [568, 661],
 [733, 348],
 [650, 205],
 [509, 204],
 [509,  64]]
points = np.array(points).reshape(8,1,2)
print(points)
for pt in zip(points,points[1:]):
    print( pt )
    x = pt[0][0]
    y = pt[1][0]
    d = math.sqrt((x[1]-y[1])*(x[1]-y[1])   (x[0]-y[0])*(x[0]-y[0]))
    print(x, y, d)
 

Выход:

 [[[224  64]]
 [[ 62 381]]
 [[224 661]]
 [[568 661]]
 [[733 348]]
 [[650 205]]
 [[509 204]]
 [[509  64]]]
(array([[224,  64]]), array([[ 62, 381]]))
[224  64] [ 62 381] 355.99578649191903
(array([[ 62, 381]]), array([[224, 661]]))
[ 62 381] [224 661] 323.4872485894923
(array([[224, 661]]), array([[568, 661]]))
[224 661] [568 661] 344.0
(array([[568, 661]]), array([[733, 348]]))
[568 661] [733 348] 353.82764165621654
(array([[733, 348]]), array([[650, 205]]))
[733 348] [650 205] 165.3420696616563
(array([[650, 205]]), array([[509, 204]]))
[650 205] [509 204] 141.00354605470034
(array([[509, 204]]), array([[509,  64]]))
[509 204] [509  64] 140.0
 

Комментарии:

1. hii спасибо за подробное решение, но я сталкиваюсь с проблемой, когда зацикливаю массив, который я показал в вопросе, моя программа возвращает массив, подобный тому, откуда я должен рассчитать длину стороны. шляпа, которую вы показали, находится в списке .

2. я попытался преобразовать массив в список с помощью array.tolist (), но он выдает ошибку как IndexError: индекс списка вне диапазона

3. То, что у вас есть, — это массив am 8x1x2. Таким образом, каждый элемент представляет собой список из 1 элемента, содержащий точку из 2 элементов. Вам нужно будет справиться с этим дополнительным уровнем. Я отредактирую ответ.

4. для x,y в zip(приблизительно,приблизительно[1:]): # печать(x[0],y[0]) d = математический.sqrt((x[0][1]-y[0][1])*(x[0][1]-y[0][1]) (x[0][0]-y[0][0])*(x[0][0]-y[0][0])) печать(‘длина между точками:’,x[0],’и’, y[0], «есть», d) с помощью этого это было сделано благодаря

5. Ах, потому что он выполняет векторное сложение, а не объединение списков. Я немного разочарован, что вы не смогли это посмотреть. Воспользуйся for pt in zip(points,np.roll(points,-1,0)):