Join 149,519 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,381 people online right now. Registration is fast and FREE... Join Now!
Hi, I am a student of Engineering. I am not studying Programming or anything like this, I just happen to have spent some time in the past with Qbasic, Vbasic and little of C for my own interest. The thing is that for a specific lesson in my university, I have to make a program that draws the curves of parametric equations similar to this one:
x={2+7cos[sinu + sin121u]}cosu pi/2500 < u < 2*pi
The funniest thing is that nobody has tought us about serious programming in any language and they ask us to write code for something like that!
Anyway, I decided to recall my programming memories and knowledge (as much as it can be!) and to try to write a code for it in QBASIC. I have also worked with VBASIC but I don;t know how to draw things on screen! Whereas in QBASIC i use the LINE command to connect two different points and show them directly in the screen.
So, I tried at first to make code that shows the results of a simpler parametric equation such as
y = cos (x)
My problem is that I want to draw each point of (x,y) separately but I dont know which command to use. So I used LINE which draws a line between two points (really!) that are being created in the calculations. The difference between two pairs of (x,y) are very small so the size of the line should be insignificant right? well my screen doesn't agree. Thats the code I wrote¨
CODE
for x = -90 to 89 y = cos(x) x2 = x+1 ' create a second pair due to lack of knowledge of how to design a single point! y2 = cos(x2)
SCREEN 1 LINE (x,y) - (x2,y2)
this is supposed to draw the results of y = cos (x)
but the graphics I get are not the way they should.
Sorry for the long post guys, if anybody can help I would appreciate, I can also use Visual Basic if anybody has a proposition to make, thanks!
This post has been edited by newbie69: 19 May, 2007 - 01:51 AM
QBasic, now there's a language i haven't seen in a long time. I believe what you want is: PSET (#1,#2), #3 where: #1 = x coordinate #2 = y coordinate #3 = colour to print the pixel.
This works similarly to the set method, which can mutate lines, etc if done correctly, but pset will draw single pixels, so you can plot out specific points.
You may want to use SCREEN 12 or 7 as well, as they are more common
QBasic, now there's a language i haven't seen in a long time. I believe what you want is: PSET (#1,#2), #3 where: #1 = x coordinate #2 = y coordinate #3 = colour to print the pixel.
This works similarly to the set method, which can mutate lines, etc if done correctly, but pset will draw single pixels, so you can plot out specific points.
You may want to use SCREEN 12 or 7 as well, as they are more common
Hi, I found out that the COS command works only with RADIUS amounts (obvious!) so I have to convert the degrees to radius first. I did that and now I can get at least the correct COS(x) results with PRINT.
Next step is to draw the results with single pixels/points.PSET is the command I needed and I would like to thank you for that. however the points are not visible at all.... I suspect they are drawn but not seen because they are outside the limits of the screen. I dont get any error message, only a blank screen. I use SCREEN 12.
The code so far, calculates the correct results but the points it draws are not visible. Can anybody suggest a way so that the PSET command starts to draw points from a specific point of the screen and goes on...?
the code is the following
CODE
SCREEN 12 FOR x = 0 TO 90 angle = x * (3.14 / 180) y = SIN(angle)
PSET (x, y), 2
NEXT x
PS. When I multiplied the x,y coordinates by 30 some points started to appear from the upper part of the screen I did it like this:
Yes, I finally figured it out... I had to make an offset for the x,y, points so that everything was visible, and with another PSET command I could draw the x-ayis as well. ofcourse the +50 and 180*y offset were made by many trials but ok! I am very happy for the moment, the equation I have to draw however is much more complex and I dont know If it can be evaluated but the thing is that the code is write for the plotting of the equation.
Thanks again for the PSET command, the rest is up to me
CODE
SCREEN 12
FOR x = 0 TO 360 angle = x * (3.14 / 180) y = SIN(angle)
PSET (50 + x, 250 + (180 * y)), 2 PSET (50 + x, 250), 4 NEXT x
Well your equation needs a little explanation. It loooks like a maping of the set (0, 2Pi) -> Reals using the expression
f(x) = (2+7*COS(SIN(x) + Sin(121*x)))*COS(x)
This is not a parametric equation. A parametric equation would be a set of equations defining coordinates, for example:
x(u) = 10 * Cos(u) y(u) = 10 * Sin(u)
So first off we need an environment to display out equation in: SCREEN 12 'sets the screen in 640x480 16Color graphics
DIM u AS DOUBLE DIM y AS DOUBLE DIM pi AS DOUBLE DIM BeginPoint AS DOUBLE DIM EndPoint AS DOUBLE DIM LoopStep AS DOUBLE
pi = ATN(1) * 4 'Calculate PI as far as Qbasic can...
BeginPoint = pi / 2500 EndPoint = 2 * pi LoopStep = pi / 25000
'The window function will allow you to choose your coordinate system ' Here I have chosen to look at the entire function ' but you could easily choose other windows to look at other parts. WINDOW(BeginPoint, -10)-(EndPoint, 10) 'Sets the coordinate system we will use LINE (BeginPoint - 1, 0)-(EndPoint + 1, 0), 8 'Draw X-Axis LINE (pi, 10)-(pi, -10), 8 'Draw Y-Axis at x=pi
'Note that this is a very high frequancy function (due to the 121 * u) so ' LoopStep must be small to get a good picture of it. FOR u = BeginPoint TO EndPoint STEP LoopStep y = (2 + 7 * COS(SIN(u) + SIN(121 * u))) * COS(u) PSET (u, y), 15 NEXT u
To make the program plot a parametric equation just add in a line: x= whatever then change the pset line to to PSET (x, y)
Hello, I didn't have the time to check the forum earlier as I was busy enough writing the program. At first, you are right about the "parametric" thing. I found out only later. We were given sets of parametric equations for example
x = (2+7*COS(SIN(x) + Sin(121*x)))*COS(x) and y = (2+7*COS(SIN(x) + Sin(121*x)))*SIN(x)
so I corrected the code, with little effort, as the rest of the stuff was already written. I just added a line and made the PSET command draw the x,y at the same time. The results were some very interesting patterns I have to admitt, (flowers, etc...).
One problem I had though was the axises, I could create the axises easily but I couldn't make the degradations on them, appear vor a better visual result of the minimum and maximum values. This couldn't be done with the PSET command. Maybe this WINDOW command you wrote about is capable of doing it, creating in other words axises with the correspondant values on them, then it would be complete 100%. But as I had to deliver the program by monday, I just made the following: Create the x-y axis with thick red lines, correctly alligned with the equation's centre, to give an idea of how the equations develop along the axises, and printed out the x-min, x-max, y-min, y-max values.
and by the way:
pi is supposed to be 180 degrees when used as range of angle values, as we all know, and not 3.14 which is its regular value for numeric calculations.
so the main part of the code for one of the five sets of equations we had is like this:
CODE
intro: '----------- initialize variables ------------- CLS SCREEN 12 resp = 0 xmax = -1000000000 xmin = 1000000000 ymax = -100000000 ymin = 1000000000 min = (9 * 180) / 500 max = 36 * 180 '--------- main calculation of X,Y --------- FOR x = min TO max STEP .01 '--------- Degrees To RAD-------------- angle = x * (3.14 / 180) '----------------------------------------------- xi = (-angle * SIN((3.14 * angle) / 8)) * COS(angle) yi = (-angle * SIN((3.14 * angle) / 8)) * SIN(angle)
'------- find min/max X,Y ------------ IF xi > xmax THEN xmax = xi END IF IF xi < xmin THEN xmin = xi END IF
IF yi > ymax THEN ymax = yi END IF IF y < ymin THEN ymin = yi END IF
PSET (300 + 1.73 * xi, 220 - (1.73 * yi)), 2
'--- I moved the plot by 300,220 so that it appears more centered '--- and multiplied the values because it was very difficult to '--- distinguish the patterns.
NEXT x
'----------- X axis --------------- FOR i = 0 TO 640 PSET (i, 220), 4 PSET (i, 221), 4 NEXT i
'----------- Y axis---------------- FOR i = 0 TO 480 PSET (300, i), 4 PSET (301, i), 4 NEXT i
'---------------- labels ---------------------- LOCATE 1, 22 COLOR 2 PRINT "plot of the parametric equation made of " LOCATE 2, 5 PRINT "x=(-u * SIN((3.14*u)/8)) * COS(u) + y=(-u * SIN((3.14*u)/8)) * SIN(u)"
LOCATE 26, 4 COLOR 8 PRINT "x min =", xmin; COLOR 9 PRINT " x max =", xmax
LOCATE 27, 4 COLOR 6 PRINT "y min =", ymin; COLOR 11 PRINT " y max =", ymax
LOCATE 15, 35 COLOR 7 PRINT "0,0"
'-------- end of program, restart option ---- LOCATE 28, 4 COLOR 7 INPUT; "(1) to return to main menu OR <ENTER> to EXIT"; resp SELECT CASE resp
CASE 1 GOTO intro
CASE ELSE
STOP END SELECT
STOP
I would like to give me your opinion about the final result, as I don't have such a programming experience but given the circumstances I believe I wrote something that matches the thing we were supposed to do in a pretty much OK way.
Pi is !!!ALWAYS!!! 3.14156265... and NEVER 180 degrees. It is true that an angle of Pi Radians happens to be equivalent to an angle of 180 degrees.
The computer does its math in Radians. It is a more natural place to work and the translation to degrees is just something that we humans like to have. You can have a program that works in degrees and translates to Radians (as your program does), or you can have a program that works in Radians... I myself prefer radians.
However your program above translates from degrees to radians.
The line IF y < ymin THEN should be IF yi < ymin THEN and there is no need for those if statments to be block statements:
CODE
IF xi > xmax THEN xmax = xi IF xi < xmin THEN xmin = xi
IF yi > ymax THEN ymax = yi IF yi < ymin THEN ymin = yi
Would work just as well, and be a little more readable.
The STOP statment is mostly used in debugging and not generally used inside of actual code. Use END as it actually terminates the program.
Programmers try to avoid the use of the GOTO statement. It is a bad habit to start. In your case it works well though you probably should have used:
CODE
INPUT "(1) to return to main menu OR <ENTER> to EXIT"; resp IF resp = 1 THEN GOTO intro END
Though you could avoid the goto by putting the WHOLE thing in a do-loop-while loop.
CODE
intro: DO ... 'program program program ... INPUT "(1) to return to main menu OR <ENTER> to EXIT"; resp LOOP WHILE resp = 1 END
Though as I said, in this case the goto is no big deal. But as you move on in programming you should try to use control structures like loops and block conditional statments to control the flow of your program (that is afterall why they are called "control structures")
Parametric equations are really cool. They are a big part of why I became interested in mathematics. Here is the source for one of the first screen savers I ever wrote -- I did this is high school so it does not follow the best programming practices, but its still cool:
CODE
'PROGRAM: PARA4A.BAS by NickDMax
'Set up constants... DIM PI AS DOUBLE DIM RAD AS DOUBLE PI = ATN(1) * 4 RAD = PI / 180
DEFINT A-Z 'Make the default datatype integer SCREEN 9 RANDOMIZE TIMER 'Ensure we have unpredictable random numbers DO f1 = INT(RND * 10): f2 = INT(RND * 10) f3 = INT(RND * 10): f4 = INT(RND * 10) ap = 1 vp = 0 DO SCREEN 9, , ap, vp 'CLS LINE (0, 0)-(639, 399), 0, BF FOR A = 0 TO 360 STEP 1 b = A + off1 ar! = A * RAD br! = b * RAD x1 = 75 * SIN(ar! * f1) + 75 * SIN(br! * f3) y1 = 75 * COS(br! * f2) + 75 * COS(ar! * f4) x1 = x1 + 320: y1 = y1 + 150 IF A = 0 THEN Ox1 = x1: Oy1 = y1 LINE (x1, y1)-(Ox1, Oy1), 4 Ox1 = x1: Oy1 = y1 NEXT A SWAP ap, vp off1 = off1 + 1 A$ = INKEY$ LOOP UNTIL A$ > "" LOOP UNTIL A$ = CHR$(27) 'The ESC key exits...
Very nice indeed... and also has a 3D touch in some of the plots... thanks again for the help! About the STOP command I was looking to find the command to end the programm before it reaches its actual end ( I had in mind the equivalent of EXIT SUB in VBASIC) but didn't find it in the HELP menu, so I used STOP to do my work! anyway, as I said I am not an experienced programmer, not even a medium one!