Треугольная математика для разработки игр - PullRequest
4 голосов
/ 21 октября 2008

Я пытаюсь сделать треугольник (равнобедренный треугольник) для перемещения по экрану и в то же время слегка повернуть его, когда пользователь нажимает клавишу со стрелкой (как вправо или влево).

Я бы хотел, чтобы нос (верхняя точка) треугольника всегда возглавлял треугольник. (Как в той старой игре с астероидами).

Моя проблема в математике, стоящей за этим. На каждом временном интервале X я хочу, чтобы треугольник двигался в «каком-то направлении», мне нужна помощь в поиске этого направления (увеличение и уменьшение x и y).

Я могу найти центральную точку (Центроид) треугольника, и у меня есть самые верхние точки x и y, поэтому у меня есть вектор линии для работы, но я не знаю, как с ним работать. .

Я думаю, что это как-то связано со старыми методами Sin и Cos и величиной (углом) поворота треугольника, но я немного заржавел в этом.

Любая помощь очень ценится.

Ответы [ 9 ]

5 голосов
/ 21 октября 2008

Арктангенс (обратный тангенс) для vy / vx, где vx и vy - компоненты вашего вектора (centroid-> tip), дает вам угол, к которому направлен вектор.

Классический арктангенс дает вам угол, нормализованный до -90 °

К счастью, ваша стандартная библиотека должна предоставлять функцию atan2 (), которая принимает vx и vy отдельно в качестве параметров и возвращает вам угол между 0 ° и 360 ° или -180 ° и + 180 ° градусов. Он также будет иметь дело с особым случаем, когда vx = 0, что приведет к делению на ноль, если вы не будете осторожны.

Смотрите http://www.arctangent.net/atan.html или просто ищите "arctangent".

Редактировать: я использовал градусы в своем посте для ясности, но Java и многие другие языки / библиотеки работают в радианах, где 180 ° = π.

Вы также можете просто добавить vx и vy к точкам треугольника, чтобы он двигался в направлении «вперед», но убедитесь, что вектор нормализован (vx² + vy² = 1), иначе скорость будет зависеть от вашего треугольника. размер.

4 голосов
/ 22 октября 2008

Вот еще немного:

Векторы представляют смещение. Смещение, перемещение, перемещение или как вы хотите это назвать, не имеет смысла без отправной точки, поэтому я назвал приведенный выше «прямой» вектор «от центроида», и поэтому «вектор центроида», вектор с x / y-компоненты точки центроида не имеют смысла. Эти компоненты дают вам смещение точки центроида от начала координат. Другими словами, pOrigin + vCentroid = pCentroid. Если вы начинаете с точки 0, а затем добавляете вектор, представляющий смещение точки центроида, вы получаете точку центроида.

Обратите внимание, что:

вектор + вектор = вектор
(добавление двух смещений дает третье, другое смещение)

точка + вектор = точка
(перемещение / смещение точки дает вам другую точку)

точка + точка = ???
(добавление двух точек не имеет смысла; однако:)

точка - точка = вектор
(разница двух точек - это смещение между ними)

Теперь об этих смещениях можно думать (по крайней мере) двумя разными способами. Вы уже знакомы с системой прямоугольная (x, y), где две составляющие вектора представляют смещение в направлениях x и y соответственно. Однако вы также можете использовать полярные координаты, (r, Θ). Здесь Θ представляет направление смещения (в углах относительно произвольного нулевого угла), а r - расстояние.

Взять, к примеру, вектор (1, 1). Он представляет собой движение на одну единицу вправо и на одну единицу вверх в системе координат, которую мы все привыкли видеть. Полярный эквивалент этого вектора будет (1,414, 45 °); то же самое движение, но представленное как «смещение 1,414 единиц в направлении угла 45 °. (Опять же, используя удобную полярную систему координат, где восточное направление равно 0 °, а углы увеличиваются против часовой стрелки.)

Соотношение между полярными и прямоугольными координатами:

Θ = atan2 (y, x)
r = sqrt (x² + y²) (теперь вы видите, где появляется правый треугольник?)

и наоборот

x = r * cos (Θ)
y = r * sin (Θ)

Теперь, поскольку отрезок линии, проведенный от центроида вашего треугольника к углу «кончика», будет представлять направление, в котором «треугольник» стоит «лицом», если бы мы получили вектор, параллельный этой линии (например, vForward = pTip - pCentroid ), Θ-координата этого вектора будет соответствовать углу, с которым сталкивается ваш треугольник.

Снова возьмите вектор (1, 1). Если бы это было vForward, то это означало бы, что координаты x и y вашей «точки наконечника» были на 1 больше, чем у вашего центроида. Допустим, центроид включен (10, 10). Это ставит угол «наконечника» на (11, 11). (Помните, pTip = pCentroid + vForward , добавив «+ pCentroid» к обеим сторонам предыдущего уравнения.) Теперь, в каком направлении обращен этот треугольник? 45 °, верно? Это Θ-координата нашего (1, 1) вектора!

4 голосов
/ 21 октября 2008

@ Mark:

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

Ваши координаты центроида и "наконечника" не являются векторами; то есть нечего думать о них как о векторах.

Вектор, который вы хотите, vForward = pTip - pCentroid, можно рассчитать, вычтя координаты угла «наконечника» из точки центроида. Атан2 () этого вектора, то есть atan2 (tipY-centY, tipX-centX), дает вам угол, к которому ваш треугольник "обращен".

Что касается того, к чему это относится, это не имеет значения. Ваша библиотека, вероятно, будет использовать соглашение, согласно которому увеличивающаяся ось X (---> направление вправо / восток, по-видимому, на всех 2D-графиках, которые вы видели) равна 0 ° или 0π. Направление Y (сверху, север) будет соответствовать 90 ° или (1/2) π.

4 голосов
/ 21 октября 2008

Мне кажется, вам нужно сохранить угол поворота треугольника и, возможно, его текущую скорость.

x' = x + speed * cos(angle)
y' = y + speed * sin(angle)

Обратите внимание, что угол в радианах, а не в градусах!

Радианы = Градусы * РадианыInACircle / ГрадусыInACircle

RadiansInACircle = 2 * Pi

DegressInACircle = 360

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

2 голосов
/ 21 октября 2008

держать центр тяжести в начале координат. используйте вектор от центра тяжести до носа в качестве вектора направления. http://en.wikipedia.org/wiki/Coordinate_rotation#Two_dimensions будет вращать этот вектор. построить две другие точки из этого вектора. переведите три точки туда, где они находятся на экране, и нарисуйте.

0 голосов
/ 30 октября 2008

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

// начальная точка

double tip_x = 10;
double tip_y = 10;

should be

double center_x = 10;
double center_y = 10;

// детали треугольника

int width = 6; //base
int height = 9;

должен быть массивом из 3 угловых пар расстояний.

angle = rotation_angle + vertex[1].angle;
dist = vertex[1].distance;    
p1_x = center_x + math.cos(angle) * dist;
p1_y = center_y - math.sin(angle) * dist;
// and the same for the other two points

Обратите внимание, что я вычитаю расстояние Y. Вас сбивает с толку тот факт, что пространство на экране инвертировано. По нашему мнению, Y увеличивается с ростом, но экранные координаты не работают таким образом.

Математика намного проще, если вы отслеживаете вещи как положение и угол поворота, а не вычисляете угол поворота.

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

0 голосов
/ 21 октября 2008

вы хотите, чтобы верхняя вершина была центром тяжести для достижения желаемого эффекта.

0 голосов
/ 21 октября 2008

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

aib , заявив, что:

Арктангенс (обратная касательная) VY / VX, где VX и VY являются компоненты вашего (центроид-> совет) вектор, дает вам угол вектора стоит.

Являются ли vx и vy координатами x и y центриода или вершины? Я думаю, что я запутался в терминологии «вектора» здесь. У меня сложилось впечатление, что Вектор - это просто точка в 2d (в данном случае) пространстве, которая представляет направление.

Итак, как в этом случае рассчитывается вектор центроида-> наконечника? Это просто центриод?

meyahoocomlorenpechtel указано:

Мне кажется, что вам нужно хранить угол поворота треугольника и возможно это текущая скорость.

Какой угол поворота относительно? Происхождение треугольника или само игровое окно? Кроме того, для будущих поворотов является ли угол углом от последнего поворота или исходной позиции треугольника?

Спасибо всем за помощь, я действительно ценю это!

0 голосов
/ 21 октября 2008
double v; // velocity
double theta; // direction of travel (angle)
double dt; // time elapsed

// To compute increments
double dx = v*dt*cos(theta);
double dy = v*dt*sin(theta);

// To compute position of the top of the triangle
double size; // distance between centroid and top
double top_x = x + size*cos(theta);
double top_y = y + size*sin(theta);
...