Математика треугольников для разработки игр

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

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

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

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

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

Любая помощь приветствуется.

Нет, это для моего собственного проекта, для моих собственных интересов. Почему? Это похоже на домашнее задание?

Mark 21.10.2008 06:43

Это имеет значение? Он просит помощи, а не codez. знак равно

Erik Forbes 30.10.2008 08:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
2
2 881
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Ответ принят как подходящий

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

Классический арктангенс дает вам угол, нормализованный до -90 ° <r <+ 90 ° градусов, однако вам нужно добавить или вычесть 90 градусов из результата в зависимости от знака результата и знака vx.

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

См. http://www.arctangent.net/atan.html или просто ищите «арктангенс».

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

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

Итак, если у меня есть этот угол, как я могу применить его, чтобы знать, как увеличивать / уменьшать значения x и y каждой точки треугольника?

Mark 21.10.2008 05:21

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

Mark 21.10.2008 05:26

Вы можете нормализовать и использовать vx и vy (просто добавьте их к координатам x / y точек). Обратите внимание, что vx = sin (r) и vy = cos (r), это прямо противоположно операции arctan.

aib 21.10.2008 05:44

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

aib 21.10.2008 05:46

извините, если я задаю глупый вопрос, но в других сообщениях по этому вопросу говорится, что значения x используют cos (), а значения y используют sin (), но в вашем комментарии они наоборот, было ли это задумано?

Mark 21.10.2008 05:52

В твоем случае это не имеет особого значения. Вы можете поменять местами грех и соз. По сути, они дают вам ту же кривую с разностью фаз PI / 2. Все, что это повлияет, - это то, куда изначально будет направлен ваш треугольник, когда ваш угол начинается с 0.

Ates Goral 21.10.2008 08:37

Но да, я хотел использовать sin () и cos () наоборот в комментариях. Дело в том, что очень легко переключаться между компонентами вектора, углом вектора и вашим смещением x / y.

aib 21.10.2008 16:13

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

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

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

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

RadiansInACircle = 2 * Пи

DegressInACircle = 360

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

Итак, если бы я использовал градусы, формула была бы такой: x '= x + speed * cos (myAngleInDegrees * ((2 * PI) / 360)) y' = y + speed * sin (myAngleInDegrees * ((2 * PI ) / 360)) ??

Mark 21.10.2008 05:22

Да, и в более сжатой форме: myAngleInDegrees * PI / 180

Ates Goral 21.10.2008 08:31

Да, 2 Pi / 360 сокращается до Pi / 180. Я пытался объяснить, почему.

Loren Pechtel 22.10.2008 06:03
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);

Применяется ли логика вычисления новых значений top_x и top_y к двум другим точкам в том же поместье?

Mark 21.10.2008 05:24

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

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

аиб заявил, что:

The arctangent (inverse tangent) of vy/vx, where vx and vy are the components of your (centroid->tip) vector, gives you the angle the vector is facing.

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

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

Meyahoocomlorenpechtel заявил:

It seems to me that you need to store the rotation angle of the triangle and possibly it's current speed.

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

Спасибо всем за помощь, я очень признателен!

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

Уверены в этом? В таких играх, как Asteroids, центр вращения помещается в центре корабля, а не на носу. Однако формулы остаются неизменными, где бы вы их ни поместили.

Loren Pechtel 22.10.2008 06:04

@Отметка:

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

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

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

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

Спасибо, айб, это очень ясно. Я очень ценю помощь!

Mark 22.10.2008 01:29

Вот еще кое-что:

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

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

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

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

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

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

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

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

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

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

и наоборот,

х = г * соз (Θ)
у = г * грех (Θ)

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

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

Во-первых, я бы начал с центроида, а не рассчитывал его. Вы знаете положение центроида и угол поворота треугольника, я бы использовал это для вычисления местоположения вершин. (Заранее прошу прощения за любые синтаксические ошибки, я только начал баловаться 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 увеличивается по мере того, как вы поднимаетесь, но координаты экрана так не работают.

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

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

Извините, но я не понимаю 2 строки: angle = rotation_angle + vertex [1] .angle; dist = вершина [1] .distance; это может быть просто синтаксис, но я просто не понимаю, что вы здесь делаете ... что такое вершина [1]? Извините, если это просто, у меня просто больше проблем с этим, чем я думал ...

Mark 30.10.2008 08:28

Предполагается, что вершина [1] представляет собой вершину треугольника, а «угол» - это его поворот от центра? что это за "дистанционная" часть?

Mark 30.10.2008 08:33

Я имею в виду, что информация о вашем треугольнике состоит из трех точек, а не только кончика. Указываю пункт 1 из 3 - массив. (Примечание: это также допускает формы, отличные от треугольника.)

Loren Pechtel 30.10.2008 20:59

Я предлагаю хранить точки как полярные координаты - угол и расстояние от центра, а не x, y от центра. Полярные координаты значительно упрощают вращение.

Loren Pechtel 30.10.2008 21:00

Понятно, спасибо за информацию, я ценю помощь. Хотя кажется, что это тоже не имеет смысла, я перевел этот вопрос с смещения на вращение, чего я на самом деле не хотел делать!

Mark 31.10.2008 00:37

Я думаю, что именно я обратил это внимание на ротацию, но это произошло потому, что я увидел в этом слабость предлагаемого вами подхода.

Loren Pechtel 31.10.2008 06:10

Другие вопросы по теме