У меня есть несколько точек в 3D, и после их соединения я создал с их помощью несколько линий. Теперь у меня есть номера строк в виде массива NumPy, но я не знаю, как соединить количество строк.
lines=np.arange (17, 31)
На самом деле номера строк поверхностей какие-то беспорядочные. Линии в двух наборах, и каждый набор параллельный (синяя и красная линии на загруженном рисунке). Я также знаю две другие вещи: последнее число изменения направления линии (sep
), а также количество точек второго набора линий (красные) (rep
).
sep=23
rep=np.array ([4,3,3,1])
На основе моего рисунка у меня есть четыре поверхности, созданные линиями с номерами 17-25-18-27
, 18-26-19-28
, 20-27-21-29
и 21-28-22-30
. Я создал следующий код для создания таких пар, но он вообще не удался:
for i in lines:
if rep[0]==rep[1]:
print (i, sep+1, i+1, sep+1)
elif rep[0]!=rep[1]:
print (i, sep+1+np.abs (rep[1]-rep[0]), i+1, sep+1+np.abs (rep[1]-rep[0])+ 1 + np.abs (rep[1]-rep[0]))
На самом деле, я хочу, чтобы алгоритм печатал следующее:
17, 25, 18, 27
18, 26, 19, 28
20, 27, 21, 29
21, 28, 22, 30
Я признателен, если кто-нибудь поможет мне создать такой алгоритм, который может генерировать пары поверхностей. На самом деле мой массив lines
больше. Я хочу найти способ создания поверхностей на основе rep
, sep
и lines
. Заранее, я ценю любую помощь. Спасибо, что уделили время.
Не очень навороченный способ — построить сетку линий, а затем собрать из сетки 4 кортежа линий.
Во-первых, преамбула:
#! /usr/bin/env python3
import numpy as np
start = 17
sep = 23
rep = np.array([4,3,3,1])
Чтобы построить сетку, обратите внимание, что здесь длина rep
— это длина сетки по оси x, а максимальное значение rep
— это длина по оси y. Однако мы строим сетку из линий, а не из точек, поэтому в каждом направлении на 1 меньше. Обратите внимание, что я использую N_y
и N_x
именно в таком порядке, чтобы простая печать отображала сетку в формате, более близком к диаграмме на картинке.
N_x = len(rep) - 1
N_y = max(rep) - 1
grid = np.zeros((N_y, N_x, 2))
Сколько горизонтальных линий в каждом столбце? Для столбца, образованного точками (x_i, y) и (x_i+1, y), это min(rep[i], rep[i+1])
- количество точек в меньшем столбце. Для столбца 0 это 0 — слева от сетки ничего нет. Это также дает нам общее количество горизонтальных линий.
Количество вертикальных линий в каждом столбце легко определить — это количество точек по оси Y — 1. (И, следовательно, общее количество вертикальных линий равно сумме rep
— длины rep
.)
kxs = [0] + [min(rep[i], rep[i+1]) for i in range(len(rep)-1)]
T_x = sum(kxs)
T_y = sum(rep) - len(rep)
T_total = T_x + T_y
lines = np.arange(start, start+T_total)
Приступаем к заполнению сетки. Индексация здесь неудобна, поскольку мы заполняем ее снизу вверх, а оси меняются местами, как упоминалось ранее. Идем слева направо и снизу вверх.
# `lines_before` is essentially, an index into the `lines` array,
# keeping track of how many lines have already been used
lines_before = 0
for i in range(N_x):
for j in range(N_y-1, -1, -1):
if j >= kxs[i+1]:
# We haven't reached the minimum depth (or height, however you think of it)
continue
grid[j,i,0] = lines[lines_before]
lines_before += 1
print(grid[:,:,0])
for i in range(N_x):
for j in range(N_y-1, -1, -1):
if j < rep[i] - 1:
grid[j,i,1] = lines[lines_before]
lines_before += 1
print(grid[:,:,1])
На данный момент вывод для чисел в вопросе:
[[19. 22. 23.]
[18. 21. 0.]
[17. 20. 0.]]
[[26. 28. 30.]
[25. 27. 29.]
[24. 0. 0.]]
Номера строк совпадают с изображением, а нули теперь указывают, где линий нет.
Теперь мы можем собирать наборы линий. Начиная сверху, и двигаясь слева направо и сверху вниз, в каждой позиции собираем горизонтальную линию там и ту, что под ней, и вертикальную линию там и ту, что справа от нее. (Тогда из изображения будут взяты (19, 18, 26, 28), (18, 17, 25, 27) и т. д.) Для каждого собранного набора, если какое-либо число равно нулю, это означает, что в нем отсутствует линию, и мы можем устранить ее. Так:
for i in range(N_x - 1):
for j in range(N_y - 1):
square = np.append(grid[j:j+2, i, 0], grid[j, i:i+2, 1])
if all(square):
print(square)
Предоставление:
[19. 18. 26. 28.]
[18. 17. 25. 27.]
[22. 21. 28. 30.]
[21. 20. 27. 29.]
Это не в том порядке, в котором вы хотите, и мы строим сетку, что может быть слишком дорого, но я оставляю порядок и оптимизацию в качестве упражнения со следующими примечаниями:
kxs
и rep
можно определить номер строки в каждой позиции сетки, поэтому сетка нам вообще не нужна.Уважаемый @muru, спасибо за то, что очень помогли. Есть ли возможность смешать их обоих? Я имею в виду, скажем, sep=25
и rep = np.array([4,3,1,1,4,4])
. Тогда у меня должно быть пять поверхностей.
Разве вы не получаете 5 наборов строк, используя модификации в моем последнем комментарии?
К сожалению, нет, это дает мне две первые поверхности, которые неверны.
В этом случае сетки больше в разных направлениях для x и y. Таким образом,
grid
само будетnp.zeros((N_y + 1, N_x + 1, 2))
, а в циклах цикл для x будет иметьfor j in range(N_y, -1, -1)
, а цикл для y будет иметьfor i in range(N_x+1)
, что дает результат[20. 19. 22. 24.]
и[19. 18. 21. 23.]
.