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

StackOverflow https://stackoverflow.com/questions/220439

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

Мы очень ценим любую помощь.

Это было полезно?

Решение

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

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

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

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

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

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

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

@Отметить:

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

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

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

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

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

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

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

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

RadiansInACircle = 2 * Pi

DegressInACircle = 360

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

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

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

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

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

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

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

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

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

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

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

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

и наоборот,

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

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

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

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

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);

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

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

  

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

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

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

meyahoocomlorenpechtel заявил:

  

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top