Computer Science Canada [source code] Modeling a wave

Author:  Tony [ Mon Apr 21, 2003 11:01 pm ]
Post subject:  [source code] Modeling a wave

Inspired by my physics class and waves unit, I've came up with a short procedure for modeling waves. I will probably be making some apps using this procedure in the future.

 code: procedure drawWave(wav,amp:real, move:int) %wav - wave length in pixels :real value %amp - wave amplitude in pixels :real value %move - displacement of wave in pixels horizontaly :int value for i:1 - move ..maxx -move drawline(i+move,round(cos(i/wav*6.3)*amp)+round(maxy/2),i+1+move,round(cos((i+1)/wav*6.3)*amp)+round(maxy/2),black) end for end drawWave

In reality its just a cosine graph, modified to allow for accurate wave modeling.

This in fact is how all graphs should be done in programming. If you're drawing dots for each X value, you'll have a lot of blank spaces unless your line is perfectly horizontal (or at 45 angle), so you have to draw a line instead. From current point to the next one.

Parameters' explanations are commented inside the procedure. Here's a sample of how you call it
 code: drawWave(25,20,0)

That will draw you a wave with 25 pixel wavelength and 20 pixel amplitude. It is in its original position (moved 0).

To find frequency you need to know the time. The frequency is maxx/waveLength/time(in seconds).

Author:  Catalyst [ Mon Apr 21, 2003 11:36 pm ]
Post subject:

i modded your proc a bit so its friendlier with real numbers (i dont like ints) also add a couple more params and made a little prog

 code: View.Set ("graphics:640;640,position:300;300,offscreenonly,nobuttonbar") var clr : int for i : 1 .. 256     clr := RGB.AddColor (1, i / 256, 0) end for procedure drawWave (x, y : real, width : real, wav, amp : real, move : real)     var count : real := (x - move)     var Y : real     loop         count += 1         Y := round ((cos (count / wav * 6.3) * amp) + y)         drawline (round (count + move), round ((cos (count / wav * 6.3) * amp) + y), round (count + 1 + move), round ((cos ((count + 1) / wav * 6.3) * amp) + y), round (((Y / maxy) * 255) + 255))         exit when count >= (x + width)     end loop end drawWave var count : real := 10 loop     count += 0.1     drawWave (0, maxy / 2, maxx, count / 100, count / 1, round (count))     View.Update     drawfillbox (0, 0, maxx, maxy, 7) end loop

 Author: Martin [ Tue Apr 22, 2003 8:33 pm ] Post subject: Lookin good guys

 Author: rizzix [ Sun May 25, 2003 7:57 pm ] Post subject: heh, guys i've come up with an easier solution! you need to know how to use OO side of turing though... i use a simple convention (cuz i'm kinda limited by turing!!), used all caps for procedure, and all lower-case for functions take note of the equation: y = a(func(k(x - d))) + c where func = (sine, cos or tan) to set the amplitude u call wave_object->A(value) to get the amplitude u call something := wave_object->a to draw the wave u call wave_object->drawWave(border : int, colour : int) to change the scale of degree-to-pixel ratio (default is 1:1 i think) u call wave_object->SCALE(value : real) attached is the wave library file. have fun!!! o btw: dont use the Tangent Wave i haven't completed it yet! but if u insist u can (just remember it gets undefined at 90 degrees)

 Author: rizzix [ Sun May 25, 2003 8:00 pm ] Post subject: hmmm..... how do i know i attached the file? i'm new here! thanks..

 Author: Catalyst [ Sun May 25, 2003 8:06 pm ] Post subject: u cant attach files in the source code area

 Author: Catalyst [ Sun May 25, 2003 8:07 pm ] Post subject: put it in submissions

Author:  rizzix [ Sun May 25, 2003 8:09 pm ]
Post subject:

ok thx

but this should work right?...
 code: % y = a(func(k(x - d))) + c     class TrigWave         export a, A, k, K, d, D, c, C,             ix, IX, iy, IY, x1, X1, x2, X2,             drawWave, scale, SCALE,             LEFT, RIGHT, UP, DOWN, lambda         var _a, _k, _d, _c : real   % a, k, d, c: of equation         var _ix, _iy : int          % initial: x and y         var _x1, _x2 : int          % range/period         var _scale : real         _scale := 1         _a := 10         _k := 1         _d := 0         _c := 0         _x1 := round (-180 * _scale)         _x2 := round (180 * _scale)         _ix := round (maxx / 2)         _iy := round (maxy / 2)         % set/get a         fcn a : real             result (_a / 10) / _scale         end a         proc A (_A : real)             _a := (_A * 10) * _scale         end A         % set/get k         fcn k : real             result _k * _scale         end k         proc K (_K : real)             _k := _K / _scale         end K         % set/get d         fcn d : real             result _d / _scale         end d         proc D (_D : real)             _d := _D * _scale         end D         % set/get c         fcn c : real             result _c / _scale         end c         proc C (_C : real)             _c := _C * _scale         end C         % set/get ix         fcn ix : int             result _ix         end ix         proc IX (_IX : int)             _ix := _IX         end IX         % set/get iy         fcn iy : int             result _iy         end iy         proc IY (_IY : int)             _iy := _IY         end IY         % set/get x1         fcn x1 : int             result round (_x1 / _scale)         end x1         proc X1 (_X1 : int)             _x1 := round (_X1 * _scale)         end X1         % set/get x2         fcn x2 : int             result round (_x2 / _scale)         end x2         proc X2 (_X2 : int)             _x2 := round (_X2 * _scale)         end X2         % get lambda         fcn lambda : real             result x2 - x1         end lambda         %set/get scale         fcn scale : real             result _scale         end scale         proc SCALE (_SCALE : real)             var old_scale : real := scale             _scale := _SCALE             A ((_a / 10) / old_scale)             K (_k / old_scale)             D (_d / old_scale)             C (_c / old_scale)             X1 (round (_x1 / old_scale))             X2 (round (_x2 / old_scale))         end SCALE         % translate left x units         proc LEFT (x : real)             D (d - x)         end LEFT         % translate right x units         proc RIGHT (x : real)             D (d + x)         end RIGHT         % translate up x units         proc UP (x : real)             C (c + x)         end UP         % translate down x units         proc DOWN (x : real)             C (c - x)         end DOWN         % draw the wave         deferred proc drawWave (border_width : real, colr : int)     end TrigWave     class SineWave         inherit TrigWave         body proc drawWave (border_width : real, colr : int)             for x : _x1 .. _x2                 drawline (x + ix, round (((_a - border_width) * sind (_k * (x - _d))) + _c) + iy, x + ix, round ((_a * sind (_k * (x - _d - 1))) + _c) + iy, colr)             end for         end drawWave     end SineWave     class CosineWave         inherit TrigWave         body proc drawWave (border_width : real, colr : int)             for x : _x1 .. _x2                 drawline (x + ix, round (((_a - border_width) * cosd (_k * (x - _d))) + _c) + iy, x + ix, round ((_a * cosd (_k * (x - _d - 1))) + _c) + iy, colr)             end for         end drawWave     end CosineWave     class TangentWave         inherit TrigWave         body proc drawWave (border_width : real, colr : int)             for x : _x1 .. _x2                 drawline (x + ix, round (((_a - border_width) * cosd (_k * (x - _d))) + _c) + iy, x + ix, round ((_a * cosd (_k * (x - _d - 1))) + _c) + iy, colr)             end for         end drawWave     end TangentWave

Author:  rizzix [ Sun May 25, 2003 8:14 pm ]
Post subject:

here's an example using it!

 code: View.Set ("graphics:800;600,offscreenonly,nobuttonbar")     var wave2 : ^SineWave     new wave2     wave2 -> A(2)     wave2 -> SCALE (2)     var x : int := 1     loop         drawGrid (20)         wave2 -> drawWave (5, blue)         wave2 -> K (150 - x)         wave2 -> C (150 - x)         x += 1         if x >= 360 then             x := 0         end if         delay (20)         View.Update         cls         wave2 -> D (360 - x)         put "Scale:          ", "1 degree : ", wave2 -> scale, " pixel(s)"         put "Range:          ", wave2 -> x1, ", ", wave2 -> x2         put "Amplitude:      ", wave2 -> a, " x 10"         put "horizontal exp: ", wave2 -> k         put "Phase Shift:    ", wave2 -> d         put "Vertical Shift: ", wave2 -> c         put "Lambda:         ", wave2 -> lambda     end loop     free wave2

Author:  rizzix [ Sun May 25, 2003 8:17 pm ]
Post subject:

oh eh almost forgot!

 code: proc drawGrid (inc : int)         for x : 0 .. maxx by inc             drawline (x, 0, x, maxy, grey)         end for         for y : 0 .. maxy by inc             drawline (0, y, maxx, y, grey)         end for         drawline (0, round (maxy / 2), maxx, round (maxy / 2), red)         drawline (round (maxx / 2), 0, round (maxx / 2), maxy, red) end drawGrid

to draw a grid

 Author: Catalyst [ Sun May 25, 2003 10:18 pm ] Post subject: cool

 Author: Tony [ Sun May 25, 2003 11:16 pm ] Post subject: looks awesome... just have attach wave parts together to make it solid

 Author: PHP God [ Mon May 26, 2003 4:26 pm ] Post subject: cool sine wave, how bout a sawtooth, or a square, or a sine-square. I'm into electronic music so this crap fascinates me.

 Author: rizzix [ Mon May 26, 2003 4:53 pm ] Post subject: oh! ok np simply subtract 1 from _d for y2 in the drawline proc ex: drawline (x + ix, round (((_a - border_width) * sind (_k * (x - _d))) + _c) + iy, x + ix, round ((_a * sind (_k * (x - _d - 1))) + _c) + iy, colr) i fixed the code above...

 Author: rizzix [ Mon May 26, 2003 5:39 pm ] Post subject: some additional info... The cool thing about this class is that it defines default values for everything so u can draw a wave by simply writing a few lines.. var wave : ^SineWave new wave wave -> drawWave(0, red) free wave By default: the wave is drawn at centre of screen but the default range is from -180 to 180 thus it technically begins drawing 180 pixels to the left of the middle the scale of the wave is 1:1 (degrees : pixels) setting the scale to 2 doubles the size, length etc, of the wave, yet display the correct values for a,k,d,c,lambda etc.. you can also set it to a value < 1, letting u to display a wave of a larger length. The amplitude of the wave is 10 pixels by default. So setting a to 2 results in an amplitude of 20 pixels you need to specify the thickness of the wave to be drawn, which by default fills the wave from the inside to the very edge. Setting a negative value results in the opposite. And yes the TangentWave is incomplete. Alas, i have no time, so if anyone is interested go ahead and extend the TrigWave class with a complete solution for the TangentWave. I'm currently working on a simple record-base DBMS solution for my ISP in school. Its a success, so far. I've eliminated all those gazillion bugs. It amazingly scalable and flexible. I'll post the complete system here (its not extremely huge, as i said it is quite simple), but only after the ISP.

 Author: Tony [ Mon May 26, 2003 6:19 pm ] Post subject: thats cool... And yeah, you should post your ISPs after you hand them in cuz some teachers think that everybody is stupid and just copies code of the net... and if its big, plz upload in file

 Author: brazilian_princess [ Thu May 29, 2003 9:39 pm ] Post subject: how do u run that??? *can u tell i suck at comps?*

 Author: krishon [ Thu May 29, 2003 9:46 pm ] Post subject: lol, funny avatar

 Author: Homer_simpson [ Thu May 29, 2003 10:02 pm ] Post subject: i think her avatar is really nice...

 Author: rizzix [ Fri May 30, 2003 3:07 pm ] Post subject: brazilian_princess wrote:how do u run that??? *can u tell i suck at comps?* well copy all that code into a file... make sure the loop is pasted towards the end of the file the press F1

 :