Как рассчитать позиции лунок в игровом поле? - PullRequest
2 голосов
/ 15 февраля 2010

Я делаю игру с Python-> PyGame-> Albow и столкнулся с проблемой генерации доски.Однако я попытаюсь объяснить проблему языковым способом.Я полагаю, что это не относится к питону.

Я разделил поколение игровых досок на несколько частей.

Первая часть создает отверстия для досок.

Отверстия содержатся в списке / массиве.Каждый объект отверстия имеет отображение углов, относящихся к другим отверстиям, которые его окружают, каждое из этих отверстий также связано с ним.(Вроде как родные элементы HTML DOM, возможна разница под любым углом)

Отверстие - это что-то вроде:

hole = {
    empty: True,
    links: {
        90: <other hole>,
        270: <another hole>,
        etc...
    }
}

Часть вторая , вычислить положение отверстияКод выглядит примерно так:

def calculate_position(hole):
    for linked_hole in hole.links:
        if linked_hole.position == None:
            #calculate linked hole's position relative to this hole
            linked_hole.position = [position relative to first hole]
            calculate_position(linked_hole)

first_hole.position = (0, 0) #x, y
calculate_position( first_hole )

Часть третья , чертежная доска.

Найдите высоту окна, увеличьте положения отверстий (рассчитано на втором шаге)соответствовать окну.Нарисуйте все.

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

Я использую простую тригонометрию для вычисления относительных положений отверстий путем преобразования угла в радианы и использования встроенного sin /cos functions.

Любая идея относительно решения или, если я ошибаюсь относительно проблемы, полезна:)

PS: я опубликуюИсходный код, если это поможет, однако чувствую, что он загромождает вещи

Спасибо за все ответы.

Люди, которые сказали, что округление, вероятно, не собиралосьчтобы быть проблемой были на месте.Я имел другой взгляд через код с учетом этого.Мне стыдно сказать, что я генерировал неправильные углы в первой части генерации платы, часть рендеринга была правильной.

Я пометил ответ Нормана как правильный, потому что он объясняет, как использовать линейную комбинациювекторов для решения проблемы.

Ответы [ 3 ]

1 голос
/ 15 февраля 2010

Если позиции отверстий хранятся как целые числа, я не сомневаюсь, что ошибка округления накапливается достаточно быстро, чтобы убить вас. Если позиции отверстий сохраняются как числа с плавающей запятой, и если при каждом вычислении у вас есть ошибка в единицу на последнем месте (ULP), я не совсем уверен, насколько быстро накапливается ошибка - но если ошибка удваивается на каждом шаге, то иметь не более 53 ссылок, прежде чем даже с плавающей запятой двойной точности не получится.

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

Сделайте шесть шагов по 30 градусов, два шага по 90 градусов и четыре шага по 180 градусов

Числа шесть, два и четыре будут точными , и как только вы вычислили все позиции как векторы, вы можете затем выполнить триггер для преобразования в (x, y) координаты всех в одном идти. Если вы беспокоитесь о скорости, вы можете кэшировать арктангенс каждого угла, и он будет даже быстрым.

Если это описание слишком краткое, дайте мне знать.

0 голосов
/ 15 февраля 2010

Я не хочу быть тем, кто предлагает это, но, начните с центра. Кроме того, вы должны посмотреть на свой код и дважды проверить на неудачное преобразование. Если дыра заканчивается на «138.2, 150.8», вам нужно сохранить дробные части, пока вы не вычислите следующую дыру.

0 голосов
/ 15 февраля 2010

Бит о точности становится относительно важным, как только мы понимаем, что эти точки будут преобразованы в пиксельные координаты, например, целые числа. Накапливай ошибку 0.5 и бац! Вы один пиксель отключены.

Итак, либо существует огромная проблема с точностью, а ошибки округления очень быстро растут, либо источник проблемы находится в другом месте. Я смотрю на это в частности, в частности:

расширить позиции отверстий (рассчитано на втором шаге), чтобы соответствовать окну

Пока я не увижу скрининг, я буду считать, что «косоглазие» означает «овал-вроде-сорта-вещь»; звучит именно то, что может выдать ошибка на этом шаге.

...