определите форму по изменению x,y в python

#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» или квадрат, используя одни и те же точки в разных порядках.