=Graphics 101 – plotting a function= 
- by tsh73
- {$creationdate}
[[toc]]
----
==Goal== 
(and history).
Once upon a time there was a person who wanted to plot some graphs. He supposedly knew his math well, but just never draw a thing in Basic. Of course he was directed to a help file; but he said "I have read through the help files on graphics and it just confuses me". Well, no wonder – help is a reference in a first place, so it's more or less OK to dump all graphic functions into one BIG page *shrugs*. There is tutorial in LB, but it surprisingly focuses on turtle graphics, and leaves plotting for the reader so to say.

So I thought I could as well write tutorial myself, with intent to cover "starting from open for graphics, via pixels, coordinates, points and lines. I guess that's all really needed, may be add printing text for labeling and flush."

So here I am. Forgive my Clatchian English.
I suppose you run LB (JB will do just fine) along as you read this tutorial.

==Non-goals== 
I am not going to discuss GUI or animation or sprites – I just going to teach how to draw a static picture. Namely, to plot a function.

==Pre-requisites== 
I suppose you already are "master of mainwin". You can calculate, check conditions, loop and print results. These are really basics, so if not, go to part one of LB / JB tutorial.

==Where to draw== 
So, suppose prior to this you worked in mainwin. It is nice but it is not designed to draw stuff on – only to print text. So, we need something to draw upon.

There two types of things that allow drawing on itself – it's a window opened for graphics, and graphicbox added to ordinary window. You can have several graphicboxes on a window and draw in all of them. Pretty cool, but for now we take simplest course –
[[code format="vbnet"]]
open "test" for graphics as #gr
#gr "trapclose [quit]"
wait

[quit]
    close #gr
    end
[[code]]
That's about as simple as it gets.
First line opens window titled "test", on which we can draw.
On my computer, it's about 300x300 pixels (more about pixels later)
(you can try to type for graphics_nsb_nf instead and get even simpler window)
Second install trapclose handler – names a label which will get called on closing window.
Third prevent our program from closing immediately :)
And two last lines are called then window is closed by Alt-F4 or by mouse – they explicitly close window and end program. (Without that, you can end up with no visible windows BUT Basic still running in memory).

Two more things.
If you do not need mainwin anymore, you type nomainwin on top of your program.
And if you need more space, you set WindowWidth and WindowHeight before opening window.

==Pixels and coordinates== 
Ahhh. Pixels. That is it, exactly?

They are just dots on your monitor. Anything you see on a monitor composed from colored dots, named pixels. The pixel is smallest element of a picture.
Your monitor just now has current resolution, like 1280x1024. It's size of screen in pixels. ("just now" 'cause it could be changed). And it's maximal size of a window you can show (and draw upon).

Each pixel has coordinates. Basically that means they are numbered from 0, left to right and top to bottom. With whole numbers – there are no pixels between 0 and 1.
[[image:graph_tutorial_p1.gif]]
(On math they teach another coordinate plane, there axes go from left to right and from bottom to top. And where are plenty place between whole points.
[[image:graph_tutorial_p2.gif]]
We are going to respect that then plotting functions).

==Make a dot== 
So. We know that screen consist of dots, and dots have coordinates.
So all we should actually do to draw a dot – make a command and give coordinates?
Almost:
[[code format="vbnet"]]
nomainwin
open "test" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "down"
#gr "set 100 100"
wait

[quit]
    close #gr
    end
[[code]]
As you see, we need to "put pen down" before drawing. (Unfortunate anachronism I might add).

We got a single black dot in the 100, 100 coordinates (100 pixels to the right and down from top-left corner of window. More exactly, from top-left corner of window client area – it's "working zone").

==Make a bunch of dots== 
But single point is barely visible. Let's make a bunch, shall we?
But how we are going to do it? Why, with loops. FOR loops will do just fine.
Let X change from 100 to 200, and Y equal to X.
But how to put these numbers inside "set" command?
Let's see. Actually, line
> {{#gr "set 100 100"}}
is a shortcut. Handy, but shortcut. Full version look so:
> {{print #gr, "set 100 100"}}
Wait! It looks familiar?
It turns out that our graphic command (as ALL graphic commands) is an ordinary PRINT operator. We print to a window (#gr is a window handle) string, containing command.
That answers question how put numbers in command. Just like in PRINT:
> {{#gr "set ";100; " ";100}}
Or
> {{X=100: Y=100}}
> {{#gr "set ";X; " ";Y}}
Just watch your spaces.

(There is handy consequence. If your drawing command does not work as expected, turn them in ordinary PRINT (by replacing {{print}} for {{#gr}} ) and examine it in mainwin.)

Clearing that, here's our program:
[[code format="vbnet"]]
nomainwin
open "test" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "down"
for X=100 to 200
    Y=X
    #gr, "set ";X;" ";Y
next
wait

[quit]
    close #gr
    end
[[code]]

==Why, it's a line! – a line==
Indeed. We just draw a line. I'm pretty sure there must be more straightforward way to draw a straight line?

Sure there are several. But most straightforward is
> {{#gr "line 100 100 200 200"}}
The numbers are coordinates of first and second points, respectively.
(You can also place a first point in dedicated command and then issue command to draw from last point to another one. That comes handy then we need to draw point-by-point chain of lines:
> {{#gr "place 100 100"}}
> {{#gr "goto 200 200"}}
)
Same thing about putting variables in commands apply. (It applies EVERYWHERE).

==Why, it's a circle! – circle==
Damn, our first bunch of points behaved too simple. Let's try something fancy, with SINE and COSINE:
[[code format="vbnet"]]
nomainwin
open "test" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "down"
pi=acs(-1)
for t=0 to 2*pi step 0.01
    X=100*cos(t)+150
    Y=100*sin(t)+150
    #gr, "set ";X;" ";Y
next
wait

[quit]
    close #gr
    end
[[code]]
What? We got pretty round circle?

Let’s see why. It’s all math, you  know.
We have that Pi number, equal 3.1415926… but much simpler to put pi=acs(-1) instead. If we change angle (t) from 0 to 2Pi (full circle, but measured in radians. Computers work in radians... that still converts to ordinary 0..360 degrees full circle, by multiplying by 180/Pi) then point (cos(t), sin(t))  will go along unit circle (circle with radius=1 and center (0,0) ) on coordinate plain. 

All we added was scaling that to radius 100 (by multiplying) and shift it's center from (0,0) to (150, 150) (by adding).

And of course there is easier way to draw a circle. Just place center point, then command to draw circle with desired radius:
> {{#gr "place 150 150"}}
> {{#gr "circle 100"}}

==But bunch of dots capable of more! (Archimedes spiral)==
So far our examples looked too complex for task solved (things drawn). And there always was another, simpler way. 

Do we need plotting point by point at all?
Why, sure we are. Look at this modification of last program. This beauty is called Archimedes spiral (and actually this is example of polar plot, that is, plot of function in polar coordinates. Never mind.)
[[code format="vbnet"]]
nomainwin
open "test" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "down"

pi=acs(-1)
nLoops=10
for t=0 to 2*pi*nLoops step 0.01
    X=100*t/(2*pi*nLoops)*cos(t)+150
    Y=100*t/(2*pi*nLoops)*sin(t)+150
    #gr, "set ";X;" ";Y
next
wait

[quit]
    close #gr
    end
[[code]]




> {{ }}
==Third Part Title== 
Text here.
[[code format="vbnet"]]
'code here
[[code]]