2010-11-05 148 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 
}