C ++ формула синусоидальной волны для прыжков с пого - PullRequest
1 голос
/ 05 ноября 2010

Мне нужно создать палку пого, которая прыгает по экрану в дугах. Я думал, что лучший способ сделать это - переместить его на волну греха. Если вершина волны равна 1, земля - ​​0, а основание волны - -1, то каждый раз, когда она достигает 0, я сбрасываю значения, чтобы снова начать синусоидальную волну. Таким образом, вместо того, чтобы следовать за типичной синусоидальной волной (0, 1, 0, -1, 0 и т. Д.), Она будет идти 0, 1, 0, 1, 0 и т. Д.

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

m_vel.x++;
float f = PI / 30 / 2;
m_vel.y = 200 * sin(f * m_vel.x);
m_vel.y = -m_vel.y;

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

Ответы [ 4 ]

6 голосов
/ 05 ноября 2010

Не уверен насчет вашей математики, вашей физике нужно немного освежиться! Пого-палка является примером движения снаряда , и ее траектория образует параболу , которая описывается квадратным уравнением .

Однако, если вы продолжите использовать неправильную синусоидальную модель : "верхняя половина" (или положительная) часть синусоидальной волны имеет длину от 0 до пи радиан. Синус представляет только y-член (высоту), у вас не должно быть x-члена, который просто определяет горизонтальный шаг для каждой точки. Там, где у вас есть 200, это максимальная высота, которую достигнет пого-палка:

height = max_height * sin( theta ) ;

, где 0 <= theta <= pi и увеличивается с течением времени. Размер приращения будет определяться скоростью движения вперед или общей дистанцией прыжка. </p>

theta_step = pi / jump_distance ;

так что к тому времени, когда вы достигнете пи радиан, вы будете двигаться с помощью jump_distance. Во время прыжка мгновенное расстояние (и, следовательно, значение x на графике) будет:

 distance = jump_distance / theta ;
2 голосов
/ 05 ноября 2010

Просто возьмите абсолютное значение волны греха. Таким образом, отрицательные части становятся положительными.

float f = abs( sin( <input here> ) );
1 голос
/ 05 ноября 2010

Хаммерите имеет билет:

double a = 100.0; // amplitude controls the height
double f = 10.0;  // frequency controls the width
double t = 0.0;   // time is the independent variable.
abs(a*sin(2.0*PI*f*t)) 

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

0 голосов
/ 05 ноября 2010

Вот недавно написанный параметрический код для синусоиды и параболической волны.

#define _USE_MATH_DEFINES // need this to get M_PI defined under VS2008
#include <math.h>

[...]

// user parameters
float screen_width = 640.0f;
float number_of_cycles_per_screen = 2.0f;
float min_wave_value = 0.0f;
float max_wave_value = 1.0f;

// sinus wave characteristics
float half_amplitude = 0.5f*(max_wave_value-min_wave_value);
float offset = half_amplitude+min_wave_value;
float f0 = 2.0f*M_PI*number_of_cycles_per_screen/screen_width;
// compute sinus wave on the whole screen width
for (float x=0.0f;x<screen_width;x+=1.0f)
{
    float sin_wave_value = half_amplitude*sin(f0*x)+offset;
    // use the value here
}

// parabola
float amplitude = 0.5*(max_wave_value-min_wave_value);
float root1 = 0.0;
float root2 = 1.0f/number_of_cycles_per_screen;
// compute parabolic wave on the whole screen width
for (float x=0.0f;x<screen_width;x+=1.0f)
{
    float xm = fmod(x,screen_width/number_of_cycles_per_screen)/screen_width;
    float para_wave_value = -amplitude*(xm-root1)*(xm-root2);
    // use the value here
}
...