#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)):