Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Calin Leafshade on Wed 16/12/2009 16:50:15

Title: A sine function with diminishing frequency
Post by: Calin Leafshade on Wed 16/12/2009 16:50:15
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?!
Title: Re: A sine function with diminishing frequency
Post by: Khris on Wed 16/12/2009 17:23:13
Here's an online function plotter:
http://www.univie.ac.at/future.media/moe/fplotter/fplotter.html
Title: Re: A sine function with diminishing frequency
Post by: suicidal pencil on Wed 16/12/2009 17:54:25
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)

Title: Re: A sine function with diminishing frequency
Post by: Calin Leafshade on Wed 16/12/2009 18:00:43
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.
Title: Re: A sine function with diminishing frequency
Post by: suicidal pencil on Wed 16/12/2009 18:27:30
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.
Title: Re: A sine function with diminishing frequency
Post by: Calin Leafshade on Wed 16/12/2009 19:06:54
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
Title: Re: A sine function with diminishing frequency
Post by: suicidal pencil on Wed 16/12/2009 19:22:16
I'm not familiar with the old SNES 'passing-out' idea. I thought it was about the character falling over :P
Title: Re: A sine function with diminishing frequency
Post by: Khris on Wed 16/12/2009 19:37:59
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.
Title: Re: A sine function with diminishing frequency
Post by: Calin Leafshade on Wed 16/12/2009 19:43:49
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.
Title: Re: A sine function with diminishing frequency
Post by: Calin Leafshade on Wed 16/12/2009 19:58:27
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;
  }
}
Title: Re: A sine function with diminishing frequency
Post by: suicidal pencil on Thu 17/12/2009 02:50:24
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.