
-----------------------------------
Tony
Mon Apr 21, 2003 11:01 pm

[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.


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

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).

-----------------------------------
Catalyst
Mon Apr 21, 2003 11:36 pm


-----------------------------------
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


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


-----------------------------------
Martin
Tue Apr 22, 2003 8:33 pm


-----------------------------------
Lookin good guys

-----------------------------------
rizzix
Sun May 25, 2003 7:57 pm


-----------------------------------
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)

-----------------------------------
rizzix
Sun May 25, 2003 8:00 pm

hmmm.....
-----------------------------------
how do i know i attached the file?
i'm new here!

thanks..

-----------------------------------
Catalyst
Sun May 25, 2003 8:06 pm


-----------------------------------
u cant attach files in the source code area

-----------------------------------
Catalyst
Sun May 25, 2003 8:07 pm


-----------------------------------
put it in submissions

-----------------------------------
rizzix
Sun May 25, 2003 8:09 pm


-----------------------------------
ok thx


but this should work right?...


% 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



-----------------------------------
rizzix
Sun May 25, 2003 8:14 pm


-----------------------------------
here's an example using it!


    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


-----------------------------------
rizzix
Sun May 25, 2003 8:17 pm


-----------------------------------
oh eh almost forgot!


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

-----------------------------------
Catalyst
Sun May 25, 2003 10:18 pm


-----------------------------------
cool  :D

-----------------------------------
Tony
Sun May 25, 2003 11:16 pm


-----------------------------------
looks awesome... just have attach wave parts together to make it solid  :wink:

-----------------------------------
PHP God
Mon May 26, 2003 4:26 pm


-----------------------------------
cool sine wave, how bout a sawtooth, or a square, or a sine-square. I'm into electronic music so this crap fascinates me.

-----------------------------------
rizzix
Mon May 26, 2003 4:53 pm


-----------------------------------
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...

-----------------------------------
rizzix
Mon May 26, 2003 5:39 pm


-----------------------------------
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.

-----------------------------------
Tony
Mon May 26, 2003 6:19 pm


-----------------------------------
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

-----------------------------------
brazilian_princess
Thu May 29, 2003 9:39 pm


-----------------------------------
how do u run that??? *can u tell i suck at comps?*

-----------------------------------
krishon
Thu May 29, 2003 9:46 pm


-----------------------------------
lol, funny avatar

-----------------------------------
Homer_simpson
Thu May 29, 2003 10:02 pm


-----------------------------------
i think her avatar is really nice...

-----------------------------------
rizzix
Fri May 30, 2003 3:07 pm


-----------------------------------
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
