I have a loop controlled by a counter from 0 to 160 (i.e a 4 second counter) and i want to create a sine function based on that counter with a frequency that slows as the loop goes on.
The function must return an integer between 0 and 3 which will be passed as a power of 2 which will give me the values 1, 2, 4 and 8 (they are used as resize factors).
I kinda know how to do this but i keep getting the mathematics wrapped round my head with all the stupid floating point conversions and stuff.
Halp?!
Here's an online function plotter:
http://www.univie.ac.at/future.media/moe/fplotter/fplotter.html
That is actually very easy. the frequency of sin θ can simply be changed by writing it as sin xθ, where x is the magnitude of change. x = 2 doubles the frequency, and x = 0.5 halves it.
So, what are you actually trying to accomplish with it?
edit: To see this for yourself, go the the link provided by Khris (thanks, Khris. That's a really helpful little tool.) and type in: sin(x), then sin(2*x), then sin(0.5*x). Here's what you get:
(http://i182.photobucket.com/albums/x313/suicidal_pencil/sinwave.jpg)
I'm trying to achieve this:
function PassOut()
{
DynamicSprite *BaseImage;
DynamicSprite *DrawingSprite;
DrawingSurface *Surface;
BaseImage = DynamicSprite.CreateFromScreenShot();
DrawingSprite = BaseImage;
Surface = Room.GetDrawingSurfaceForBackground();
int counter = 1;
float ResizeFactor = 1.0;
float width = 320.0;
float height = 200.0;
float functionfrequency = 1.0;
while (counter < 200)
{
Surface.Clear(16);
DrawingSprite = DynamicSprite.CreateFromExistingSprite(BaseImage.Graphic);
DrawingSprite.Resize(FloatToInt(width), FloatToInt(height));
DrawingSprite.Resize(320, 200);
//ResizeFactor = FloatToInt(Maths.RaiseToPower(2.0, IntToFloat(FloatToInt((Maths.Sin(IntToFloat(counter / 4) ) + 1.5 * 1.5))) ) );
ResizeFactor = Maths.Sin(IntToFloat(counter / 4) * functionfrequency) * 4.0 + 5.0;
width = 320.0 / ResizeFactor;
height = 200.0 /ResizeFactor;
Surface.DrawImage(0, 0, DrawingSprite.Graphic);
Wait(1);
DrawingSprite.Delete();
counter ++;
functionfrequency -= 0.005;
}
}
I want to recreate the classic "passing out" effect seen on alot of old snes games.. especially the old Final Fantasys.
I think i need to decrease the coefficient of x exponentially rather than linearly.
I do not think you are using the Maths.Sin() function correctly. I think a quadratic function would serve your purposes better than a trigonometric function.
so, instead of using f(x) = sin(x), a better equation for this might be f(x) = -x^y, because the motion of someone passing out better represents a parabola, then a sine wave.
the reason i chose a trigonometric function was to simulate the whole 'slipping in and out of conciousness' thing.
A quadratic wouldnt give this effect
I'm not familiar with the old SNES 'passing-out' idea. I thought it was about the character falling over :P
Try this:
ResizeFactor = Maths.Sin(Maths.RaiseToPower(IntToFloat(counter), 0.5))*1.5+1.5;
ResizeFactor = Maths.RaiseToPower(2.0, ResizeFactor);
Additionally, you can do this:
o = FloatToInt(-0.5*ResizeFactor);
Surface.DrawImage(o, o, DrawingSprite.Graphic);
Surface.Release();
(Also move the Surface = Room.GetDrawingSurfaceForBackground(); line to the beginning of the loop then.)
o will slightly offset the zoomed version so the pixels will "stay" and not diverge to the right and down.
well i did try to find a youtube video but its not the kind of thing people take videos of :p
Essentially the screen pixellates to various degrees, in and out. Like the image is blurring.
so i used a sine function to dictate the 'blurring' effect... however it doesnt quite look right since it pulses in and out in a regular fashion.. it should be more like slowly closing and opening your eyes whilst finding it more and more difficult to keep them open each time.
that looks ok,
my latest code is
function PassOut()
{
DynamicSprite *BaseImage;
DynamicSprite *DrawingSprite;
DrawingSurface *Surface;
BaseImage = DynamicSprite.CreateFromScreenShot();
DrawingSprite = BaseImage;
int counter = 1;
int Transparency;
float ResizeFactor = 1.0;
float width = 320.0;
float height = 200.0;
float functionfrequency = 1.0;
while (counter < 220)
{
Surface = Room.GetDrawingSurfaceForBackground();
Surface.Clear(16);
DrawingSprite = DynamicSprite.CreateFromExistingSprite(BaseImage.Graphic);
DrawingSprite.Resize(FloatToInt(width), FloatToInt(height));
DrawingSprite.Resize(320, 200);
//ResizeFactor = FloatToInt(Maths.RaiseToPower(2.0, IntToFloat(FloatToInt((Maths.Sin(IntToFloat(counter / 4) ) + 1.5 * 1.5))) ) );
//ResizeFactor = Maths.Sin(IntToFloat(counter / 4) * functionfrequency) * 4.0 + 5.0;
ResizeFactor = Maths.Sin(Maths.RaiseToPower(IntToFloat(counter), 0.5))*1.5+1.5;
ResizeFactor = Maths.RaiseToPower(2.0, ResizeFactor);
width = 320.0 / ResizeFactor;
height = 200.0 /ResizeFactor;
int o = FloatToInt(-0.5*ResizeFactor);
if (counter > 200) Transparency = 90 + (counter - 200) / 2;
else Transparency = FloatToInt(ResizeFactor) * 10;
Surface.DrawImage(o, o, DrawingSprite.Graphic, Transparency );
Wait(1);
DrawingSprite.Delete();
counter ++;
functionfrequency -= 0.005;
}
}
Quote from: Calin Leafshade on Wed 16/12/2009 19:43:49
...since it pulses in and out in a regular fashion.. it should be more like slowly closing and opening your eyes whilst finding it more and more difficult to keep them open each time.
sounds like you need to program in a virtual version of a Bridge Rectifier (http://en.wikipedia.org/wiki/Diode_bridge)
It would look something like this:
if(Maths.Sin(factor*x) < 0) result = (Maths.Sin(factor*x)-Maths.Sin(factor*x))+Maths.Sin(factor*x);
else result = Maths.Sin(factor*x);
factor -= 0.05;
Basically, if the result is negative, then flip it. Else, leave it alone. It would give you a graph that looks like a landscape of steep hills, rather than a hill, then valley, then another hill, the
another valley, and etc.