#python #geometry
Вопрос:
Я использую python для отслеживания изменений x,y мыши в течение определенного периода времени, чтобы определить форму. Например, диагональная линия , идущая на юго-запад, будет иметь изменение x-y [1,1]
, а v-образная форма может иметь рисунок [[1,1],[1,-1]]
.
Это хорошо работает, когда фигура построена в том же направлении и из той же точки, что и раньше, однако вы можете построить квадрат из четырех разных начальных положений по часовой стрелке или против часовой стрелки. Если бы мы попытались обнаружить все возможные конфигурации, список выглядел бы так:
# Clockwise
[[0,1],[1,0],[0,-1],[-1,0]]
[[1,0],[0,-1],[-1,0],[0,1]]
[[0,-1],[-1,0],[0,1],[1,0]]
[[1,0],[0,1],[-1,0],[0,-1]]
# Counter-Clockwise
[[0,-1],[1,0],[0,1],[-1,0]]
[[-1,0],[0,-1],[1,0],[0,1]]
[[0,1],[-1,0],[0,-1],[1,0]]
[[-1,0],[0,1],[1,0],[0,-1]]
Есть ли способ проверить,будет ли данный список изменений x, y образовывать квадрат без необходимости создавать таблицу поиска для каждой возможности?
Ответ №1:
Да, ты можешь! Если вы ожидаете, что фигура будет состоять из одних и тех же n
точек, но только пройденных либо по порядку, либо в обратном порядке от любой начальной точки, то вы можете проверить, можете ли вы вытащить все точки по порядку, не пропуская их, кроме как в конце массива:
def verify_candidate(candidate, reference):
candidate_start = candidate[0]
if candidate_start not in reference or len(candidate) != len(reference):
return False
rfi = reference.index(candidate_start)
for pti in range(len(candidate)):
if candidate[pti] != reference[rfi]: # if, at any index, there is a mismatch, then fail.
return False
rfi = (rfi 1) % len(reference) # avoid index error
return True
verify_candidate(user, square)
verify_candidate(user, list(reversed(square)))
Ответ №2:
Вы можете использовать наборы вместо списков и кортежи вместо списков для отслеживания изменений xy (вы не можете использовать списки внутри наборов, потому что списки изменчивы и, следовательно, не могут быть хэшированы).
square = {(0,-1), (1,0), (0,1), (-1,0)}
user_mov = {(1,0), (0,-1), (-1,0), (0,1)}
square == user_mov
# True
Если движение может содержать точку дважды, и вы хотите убедиться, что оно происходит дважды, вы не можете использовать наборы, а вместо этого можете сортировать списки и сравнивать их
square = [[0,-1], [1,0], [0,1], [-1,0]]
user_mov = [[1,0], [0,-1], [-1,0], [0,1]]
sorted(square) == sorted(user_mov)
# True
Комментарии:
1. Это недостаточно надежно для повторной перетасовки точек. Можно нарисовать «Z» или квадрат, используя одни и те же точки в разных порядках.