В 2D игре я просто хочу нарисовать траекторию стрелки в полете. С помощью приведенного ниже кода траектория (парабола) выглядит правильно, а угол (или поворот) или стрелка - нет.
float g = -9.8f;
float x = (launchVelocity * time);
float y = (launchVelocity * time) + (0.5f * g * (float)Math.Pow(time, 2));
float angle = (float)Math.Tanh(y / x);
Что мне не хватает? Благодарю.
projectile-physics
Мартин
источник
источник
Ответы:
Arctanh
дает вам касательную для гиперболической кривой! Насколько я знаю, ваша парабола не является гиперболой.Но у нас есть хорошие новости: легче найти касательную для вашей параболы. Уравнение
Где твой
launchVelocity
. Теперь наклон вашей стрелы:Вы можете использовать безопасность
Arctan
сейчас, если хотите.Некоторая дополнительная информация о физике:
Примерная траектория, которую вы моделируете, относится к центру масс вашей стрелы. Когда вы говорите «положение» (x, y), вы говорите о положении центра масс. Центр масс для стрелки находится немного вперед от средней точки, и вы должны принять это во внимание, если собираетесь рисовать стрелку.
Имейте в виду, что вы не учитываете инерционный импульс стрелки (который может сильно варьироваться, если вы запускаете гигантскую баллисту), и вы не учитываете динамику движения стрелы: полет стрелы из лука не будет следовать параболическому пути!
источник
Вы хотите угол наклона стрелки в любой момент времени. Вы вспомнили, что для вычисления угла есть касательная. Но вот где ваше мышление начало идти не так:
Итак, если вы пренебрегаете воздушным трением, то x-скорость стрелки постоянна.
Сначала разложим скорость на составляющие x и y. Вы можете снимать под углом 45 или 60 градусов. Так что вам нужна скорость запуска и угол, это не скаляр.
Во-вторых, вычислите все как двойные, а не как плавающие. Вы недостаточно развиты, чтобы знать, когда ошибка округления не убьет вас, так что не пытайтесь. В любом случае, это не очень хорошая экономия времени.
В-третьих, не используйте Math.pow, он медленный и не такой точный, как умножение на целые числа. Также вы можете сэкономить много времени, используя форму Хорнера (см. Ниже)
Если вы отчаянно нуждаетесь в производительности, вы можете даже предварительно рассчитать 0,5 * g, но приведенный выше код отнимет у вас 90% пути, не делая ничего слишком сумасшедшего. Если вы хотите, тесты делают это 10 миллионов раз, это, правда, не так уж много времени, но в процентном отношении это довольно много - библиотеки в Java работают очень медленно
Итак, если вы хотите угол, под которым стрелка должна идти, то вы хотите, чтобы
И в этом случае это будет работать, потому что dx является константой. Но в общем случае dx может быть нулевым, поэтому вы обычно хотите использовать:
которая является функцией, специально разработанной для этой работы.
Но, как я уже сказал, библиотечные функции в Java ужасно медленные, и в этом случае есть лучший способ сделать это без упоминания @FxIII выше.
Если горизонтальная скорость всегда v0x, а вертикальная скорость:
тогда ваша дельта: vx, vy
Вам не нужен угол. Если вы хотите нарисовать стрелку, используйте что-то вроде:
сюжет (x, y, x + vx, y + vy);
Я не знаю, что вы рисуете, поэтому, если вам нужен угол, чтобы повернуть его (как вы используете JOGL), тогда обязательно используйте угол.
Не забудьте, если вы используете opengl, чтобы повернуть угол обратно в градусы, потому что ATAN2 возвращает радианы:
источник
Tanh () (гиперболический тангенс ) принимает угол в качестве параметра, но вы задали ему соотношение сторон.
Что вы действительно хотите, так это использовать гиперболический арктангенс , который принимает соотношение сторон в качестве параметра и возвращает угол. (Назовите это может быть «atanh», «atanh2», «arctanh» или что-то подобное; похоже, они сильно различаются в разных математических библиотеках)
источник