2010-11-05 146 views
1

我需要创建一个弹跳在弧形屏幕上的弹簧杆。我在想,做这件事的最好方法就是把它放在正弦波上。如果波的顶部是1,地面是0,波的底部是-1,那么每次碰到0时,我会重置这些值以再次开始正弦波。因此,不是遵循典型的正弦波(0,1,0,1,0等),而是遵循0,1,0,1,0等。C++正弦波跳跃弹跳公式

不幸的是,我的数学很糟糕,我一直在尝试几个小时来开发一个公式。目前,我只是试图制造一个正常的正弦波,上半部分模仿跳弹簧跳跃,似乎甚至没有那么远。我最接近的是:

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

我需要波浪很窄,高点要相当高。上面的公式从第一次迭代开始就OK了,但是波浪变宽了,高点和低点彼此接近。任何人都可以帮助数学noob出来吗?

+7

你可能要考虑一个[抛物线(http://en.wikipedia.org/wiki/Parabola)代替,因为这是实际发生的情况。 – 2010-11-05 09:55:46

+3

如果你只是想得到一个正弦波,所有的负峰都被正峰代替,你可以使用绝对值函数,就像在abs(sin(...))中一样。但是,从问题的第二部分来看,我不确定这是否是您想要的。 – Hammerite 2010-11-05 09:59:43

+0

我建议你试试Cliffords的答案,因为它有一个非常简单的实现,如果你一步一步做。只需跟踪位置速度和重力。对于每一步,您将x和y速度添加到x和y位置+将重力添加到y速度。然后你只要改变Y速度的迹象,如果(y <= 0)y_vel = - y_vel; – 2010-11-05 10:39:37

回答

6

不知道你的数学,你的物理需要一些刷牙!弹跳杆是projectile motion的一个示例,其弹道形成parabola,其描述为quadratic equation

但是你应该坚持使用不正确的正弦模型:正弦波的“上半部分”(或正极)部分从0运行到pi弧度。正弦只表示y项(高度),你不应该在那里有一个x项,它只是决定每个点的水平步长。当你有200,表示最大高度弹簧单高跷将达到:

height = max_height * sin(theta) ; 

其中0 < = THETA < =π和递增随着时间的推移。增量的大小将由前进速度或总跳跃距离决定。

theta_step = pi/jump_distance ; 

这样,当你达到pi弧度时,你将会被jump_distance移动。在该跳转瞬时距离(并且因而在一个情节的x值)将是:

distance = jump_distance/theta ; 
2

只要取一个正弦波的绝对值。 因此,负面的零件变为正面。

float f = abs(sin(<input here>)); 
1

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

不要忘了正弦函数需要弧度,让你在作为参数传递的值必须在合适的单位。

+0

'Math.a'?单是罪? – 2010-11-05 10:26:30

+0

对不起,我在这里写Java。 – duffymo 2010-11-05 11:05:27

0

这里是既窦波和抛物线波形新鲜编写,参数代码。

#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 
}