Reputation: 27
I need to create a pogo stick that jumps across the screen in arcs. I was thinking the best way to do this would be to move it on a sin wave. If the top of the wave is 1, the ground is 0 and the bottom of the wave is -1, then every time it hits 0 I would reset the values to start the sin wave again. So instead of following the typical sin wave (0, 1, 0, -1, 0 etc) it would go 0, 1, 0, 1, 0 etc.
Unfortunately my math is pretty terrible and I've been trying for hours to develop a formula. At the moment I'm just trying to make a normal sin wave where the top half emulates a pogo stick jumping, can't seem to even get that far. The closest I have is:
m_vel.x++;
float f = PI / 30 / 2;
m_vel.y = 200 * sin(f * m_vel.x);
m_vel.y = -m_vel.y;
I need the waves to be quite narrow, and the high point to be quite high. The above formula starts off ok for the first iteration but then the waves get wider and the high and low points close in on each other. Can anyone help a math noob out?
Upvotes: 1
Views: 3392
Reputation: 308998
Hammerite has the ticket:
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))
Don't forget that the sine function requires radians, so the value you pass in as a parameter must be in the right units.
Upvotes: 1
Reputation: 6905
Here is the fresh-written, parametric code for both a sinus wave and a parabolic wave.
#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
}
Upvotes: 0
Reputation: 93556
Not sure about your math, your physics needs some brushing up! The pogo stick is an example of projectile motion and its trajectory forms a parabola, which is described by a quadratic equation.
However should you persist with the incorrect sinusoidal model: The "top half" (or positive) part of a sine wave runs from 0 to pi radians. The sine represents only the y term (height), you should not have an x term there, that simply determines the horizontal step for each point. Where you have 200, that represents the maximum height the pogo stick will reach:
height = max_height * sin( theta ) ;
where 0 <= theta <= pi, and is incremented over time. The size of the increment will be determined by the forward speed, or total jump distance.
theta_step = pi / jump_distance ;
so that by the time you have reached pi radians, you will have moved by jump_distance. During the jump instantaneous distance (and therefore the x value in a plot) will be:
distance = jump_distance / theta ;
Upvotes: 6
Reputation: 16111
Just take the absolute value of a sin wave. So the parts that are negative are turned positive.
float f = abs( sin( <input here> ) );
Upvotes: 2