Формула синусоидальной волны С++ для прыжков с пого-палки

Мне нужно создать пого-стик, который прыгает по экрану дугами. Я думал, что лучший способ сделать это - переместить его на волне греха. Если вершина волны равна 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;

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


person games_dev85    schedule 05.11.2010    source источник
comment
Вместо этого вы можете рассмотреть параболу, так как именно это происходит на самом деле.   -  person Greg Hewgill    schedule 05.11.2010
comment
Если вы просто хотите получить синусоиду со всеми отрицательными горбами, замененными положительными горбами, вы можете просто использовать функцию абсолютного значения, как в abs(sin(...)). Однако из второй части вашего вопроса я не уверен, действительно ли это то, чего вы хотите, или нет.   -  person Hammerite    schedule 05.11.2010
comment
Я предлагаю вам попробовать ответ Клиффорда, поскольку он имеет чрезвычайно простую реализацию, если вы делаете это шаг за шагом. Просто следите за положением скорости и гравитации. Для каждого шага вы добавляете скорости x и y к положению x и y + добавляете гравитацию к скорости y. Затем вы просто меняете знаки скорости по оси y при ударе о землю, если (y‹=0) y_vel = - y_vel;   -  person Captain Giraffe    schedule 05.11.2010


Ответы (4)


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

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

height = max_height * sin( theta ) ;

где 0 ‹= тета ‹= пи и увеличивается со временем. Размер приращения будет определяться скоростью движения вперед или общей дистанцией прыжка.

theta_step = pi / jump_distance ;

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

 distance = jump_distance / theta ;
person Clifford    schedule 05.11.2010

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

float f = abs( sin( <input here> ) );
person C Johnson    schedule 05.11.2010

У Hammerite есть билет:

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

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

person duffymo    schedule 05.11.2010
comment
Извините, я пишу Java здесь. - person duffymo; 05.11.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
}
person Stéphane    schedule 05.11.2010