Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sine wave program
#1
Here's a little something I made in FB. It goes along with the review I'm doing in math right now.
Change the constants to get different waves.
Code:
'SINEWAVE.BAS
'By Zachary Vernon
'Draws a sinewave with domain 0<=x<=360.
'Change AMPLITUDE and PERDIODS constants to obtain different results.
CONST AMPLITUDE=100
CONST PERIODS=5
SCREENRES 800,600
WINDOW (0,0)-(800,600)
CONST PI AS DOUBLE=3.1415926
DIM AS DOUBLE Degrees,Y,OldY
FOR I=0 TO 360
    Degrees=(PI/180)*I
    Y=300+(SIN(Periods*Degrees)*(AMPLITUDE/2))
    LINE (I-1,OldY)-(I,Y)
    OldY=Y
    IF I/10=I\10 AND I<>360 THEN LINE (I,300)-(I+5,300),9
NEXT
SLEEP
f only life let you press CTRL-Z.
--------------------------------------
Freebasic is like QB, except it doesn't suck.
Reply
#2
Hi, Zachary, sine plots are an interesting way of making graphics and also learning about trigonometry. I hope you don't mind if I mention a couple of things.

There are a number of ways of measuring angles. You seem to be confusing two of them a bit.

1. degrees, there are 360 in a complete circle.
2. radians, there are (2 * PI) radians in a circle.

Your loop variable is called I, but it is actually holding the number of degrees, (Clue: FOR 0 TO 360) then in the loop, you multiply them (the degrees) by pi/180, which converts them to radians, and put the result in a variable, but you call that variable 'degrees'!

Your variable which you call "amplitude" is set to 100 in the declarations, but you divide it by 2, in the loop, so you are plotting a sine wave with an amplitude of 50. (The "amplitude" of a sine wave is the height (or depth) of one of the peaks, not the peak-to-peak value)

I am sure your teacher will say that you are putting too many calculations iside the loop, which only need to be done once. This slows your code down, especially divides. That may not matter in a graphics demo where you run it once and then look at the result, but you may soon be writing programs which do a lot more calculations.

Also the cute little dotted line showing zero is fine, but you are testing every degree whether to draw it or not. Take it out of the loop!!!

Here's a rough example of how I would do it

This is no way perfect code but it shows some of the things I mentioned.

Code:
CONST AMPLITUDE=50
CONST PERIODS=5

' if you know the screen width you can
' easily make the graph fit the screen width or part of it
const screenwidth=800
const screenheight=600
SCREENRES screenwidth, screenheight
WINDOW (0,0)-(screenwidth, screenheight)

CONST PI AS DOUBLE=3.1415926

'do the pi/180 calculation only once!!!
CONST RCONV as double = PI/180

DIM AS DOUBLE Degrees,Y,OldY
DIM AS DOUBLE radians
DIM AS INTEGER maxangle
dim as double x1,x2
dim as double xfactor

'how many cycles to show
maxangle = 360 * periods

'fit 'em to the screen
xfactor = screenwidth/maxangle

'make zero amplitude halfway up screen
const zline as integer = screenheight / 2

FOR degrees=0 TO maxangle
        radians=degrees * RCONV
        x = degrees * xfactor
        Y=zline+AMPLITUDE*(SIN(radians))
        'print degrees, y
        LINE (x-1,OldY)-(x,Y)
        OldY=Y
NEXT degrees

for d = 0 to maxangle step 10
        x1= d * xfactor
        x2= (d+1)* xfactor
        line (x1,zline)-(x2,zline),9
next d

SLEEP
Reply
#3
Hi Contrex.
A couple of things I should mention before I get started. First, this isn't for school, it's just random personal interest. Second, lots of what you mentioned is exactly what I was thinking while writing the program! Big Grin
First of all, the variable I use in the FOR...NEXT loop is "I" because it stands for Iterations. In a way this is more descriptive, because all it does is count how many iterations the loop has executed.
Regarding the AMPLITUDE/2 part. You are absolutely right! It's funny, I was trying to be insightful while programming it so I thought that it needed the division in order to make a wave with amplitude 100 as opposed to 200. I was wrong, thanks for making me see the light. BTW I do know that amplitude is distance from peak to trough divided by two, in other words deviation from the mean line. Whew! That was a bit embarassing for me! :wink:
You are right regarding the dotted line, but I was writing the program with a demo in mind. Were I to program something involving long calculations and millions of iterations, I would draw the line first.
About the WINDOW part. I'm only using that so that I can switch to paper-style Cartesian coordinates.

Thanks again for the reply, and you have some nice code there.
Here's my corrected code:
Code:
CONST AMPLITUDE=100
CONST PERIODS=5
SCREENRES 800,600
WINDOW (0,0)-(800,600)
CONST PI AS DOUBLE=3.1415926
DIM AS DOUBLE Degrees,Y,OldY
FOR I=0 TO 350 STEP 10
    LINE (I,300)-(I+5,300),9
NEXT
FOR I=0 TO 360
    Degrees=(PI/180)*I
    Y=300+(SIN(Periods*Degrees)*AMPLITUDE)
    LINE (I-1,OldY)-(I,Y)
    OldY=Y
NEXT
SLEEP
f only life let you press CTRL-Z.
--------------------------------------
Freebasic is like QB, except it doesn't suck.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)