X-Y Graphics
BlitzPlus Forums/BlitzPlus Programming/X-Y Graphics
| ||
In working with passive parabolic antenna concepts, I wanted a graphing tool that would graph from equations, not from freehand entries. Not too much out there that will do this, so I ended up borrowing a couple of ideas and writing my own. I included some of the comments and equations that I have been playing with to show how it works, but you can modify the program to plot and display any y=f(x) equation that fits within the bounds. Play with the mouse and keys to figure out how the controls work, or cheat and read the embedded comments. ;Parabolic Antenna Calculator Program ;The speed of light in a vacuum is approximatly 299,792,458 m/s (186282 miles/sec) ;The speed of light in air is approximatly .03% slower (299,702,547.2 m.s) ;The lowest frequency of 802.11g is 2.4GHz, the highest is 2.4835GHz ;A full wave length at 2.4Ghz in air is approximately 12.4876 mm ;basic parabolic equations: ; basic form of equation: y=ax^2 ; find value For a above: a=h(w/2)^2 'h=max height, w=max width ; length of parabolic arc: l=1w*(1+2/3*(2d/l)^2-2/5*(2d/l)^4+ ... ; length of parabolic arc: n=h/w: ; l=2w*(Sqr(n^2+1/16)+1/(16n)(ln(n+Sqr(n^2+1/16)+ln4) ; area within parabola: A=2hw/3 ; height h(x) at w(x): h(x)=h/w^2*(w^2-w(x)^2) ; width w(x) at h(x): w(x)=w*Sqr((h-h(x)^2)/h) ; Vertex at (h.k), vertical alignment, a is negative (upside down U): ; Distance from Vertex To focus point (p) is = a ; Distance from Vertex To directrix Line = a ; Latus rectum (Line through focus parallel To directrix) = 4a in length Global xmin=-30 ;lowest value for x to be graphed Global xmax=30 ;highest value for x to be graphed Global scale#=5 ;scale the resulting plot by some factor Global wmax=4620 ;rightmost viewable window pixel reference Global hmax=4620 ;bottommost viewable window pixel reference Global wmin=0 ;leftmost viewable window pixel reference Global hmin=0 ;topmost viewable window pixel reference Global wmid=wmax/2 ;center of viewable area horizontally Global hmid=hmax/2 ;center of viewable area vertically Global zoom=10 ;magnifier for windows viewpoint Global grid=1 ;distance of displayed grid marks Global width=800 ;number of pixels horizontally Global height=600 ;number of pixels vertically Global woffset=width/2 ;viewpoint width offset, all factors included Global hoffset=height/2 ;viewpoint height offset, all factors included Global showscale=0 ;toggles bottom and right scale display Graphics width,height,16,2 ;pick your windows size and colors SetBuffer BackBuffer() ;do plotting out of sight owoffset=woffset ohoffset=hoffset ozoom=zoom Flip Cls Goto redraw While Not KeyHit(1) If KeyDown(30) Or KeyDown(78) Then ;"A" or "+" zoom in If zoom<1000 Then zoom=zoom+1+zoom/50 Goto redraw EndIf EndIf If KeyDown(44) Or KeyDown(74) Then ;"Z" or "-" zoom out If zoom>1 Then zoom=zoom-1-zoom/50 Goto redraw EndIf EndIf If KeyDown(75) Or KeyDown(203) Or KeyDown(219) Then ;left arrow (offset right) woffset=woffset+10 Goto redraw EndIf If KeyHit(31) Then ;"S" show/hide scales at bottom and right side showscale=Not showscale Goto redraw EndIf If KeyDown(71) Then ;left and up (offset down & right) woffset=woffset+10 hoffset=hoffset+10 Goto redraw EndIf If KeyDown(72) Or KeyDown(200) Then ;up arrow (offset down) hoffset=hoffset+10 Goto redraw EndIf If KeyDown(73) Then ;up and right (offset down and left) woffset=woffset-10 hoffset=hoffset+10 Goto redraw EndIf If KeyDown(77) Or KeyDown(205) Or KeyDown(220) Then ;right woffset=woffset-10 Goto redraw EndIf If KeyDown(79) Then ;down and left (offset up and right) woffset=woffset+10 hoffset=hoffset-10 Goto redraw EndIf If KeyDown(81) Then ;down and right (offset up and left) woffset=woffset-10 hoffset=hoffset-10 Goto redraw EndIf If KeyDown(80) Or KeyDown(208) Then ;down (offset up) hoffset=hoffset-10 Goto redraw EndIf If KeyHit(199) Then ;home key (toggle with previous home setting) h=woffset woffset=owoffset owoffset=h h=hoffset hoffset=ohoffset ohoffset=h h=zoom zoom=ozoom ozoom=h Goto redraw EndIf If KeyDown(207) Then ;end key (set previous home setting to current) owoffset=woffset ohoffset=hoffset ozoom=zoom EndIf mxs=MouseXSpeed() ;get the mouse x position mys=MouseYSpeed() ;get the mouse y position If MouseDown(1) ;check for mouse left button down woffset=woffset+mxs ;if mouse, update width offset hoffset=hoffset+mys ;if mouse, update height offset .redraw ;perform screen redraws when necessary Cls drawgraph() ;first, we redraw the grid view in the window ;-------MODIFY THE FOLLOWING SECTION FOR WHATEVER EQUATIONS(S) YOU WANT TO PLOT------- m$="y=x^2/100" ;this is the equation that we want to show and plot length#=0 ;begin with a length of zero For x#=xmin*scale To xmax*scale ;this is the equation plot process y#=x#*x#/100 ;this is the equation in practice for each value of x If x#>xmin*scale Then ;Plot line segments between consecutive points Line ox#*zoom+woffset,hoffset-oy#*zoom,x#*zoom+woffset,hoffset-y#*zoom lx#=x#-ox# ;remember the previous x coordinate ly#=y#=oy# ;remember the previous x coordinate lx#=lx#*lx#+ly#*ly# ;calculate the direct length between consecutive points If lx#>0 Then length#=length#+Sqr(lx#) ;maintain a sum of the lengths Else Plot x#*zoom+woffset,hoffset-y#*zoom ;plot the initial points EndIf ox#=x# oy#=y# Next ;-----------------------END OF SECTION FOR EQUATION PLOTTING-------------------------- Flip ;display the equation as plotted Viewport width-Len(m$)*8,height0,width,height0+13 ;pick text area to clear Cls ;clear text area Locate width-Len(m$)*8-1,height0 ;position to write text Write m$ ;write equation plotted Goto redraw1 ;finish redrawing text EndIf xpos=(MouseX()-woffset)/zoom ypos=(hoffset-MouseY())/zoom .redraw1 ;redraw text when necessary n$="("+xpos+","+ypos+") " ;put mouse coordinates into n$ Viewport width0,height0,Len(n$)*8+1,height0+13 ;pick test area to clear Cls ;clear text area Locate width0,height0 ;position to write text Write n$ ;write coordinates om screen Viewport width0,height0,width,height ;resize to the normal size screen Wend Function drawgraph() sizing=grid*zoom ;set the side of the area to be drawn Color 50,50,50 ;make the gridlines a low level grey color x=woffset Mod sizing ;determine the offset for the first grid line While x<=wmax ;create all vertical grid lines Line x,hmin,x,hmax x=x+sizing Wend y=hoffset Mod sizing ;determine the offset for the first grid line While y<=hmax ;create all horizontal grid lines Line wmin,y,wmax,y y=y+sizing Wend If showscale Then ;determine if the scales are to be drawn j#=sizing*5 ;scale lines are every fifth grid line Color 255,255,255 Line width0,height-35,width,height-35 ;the horizontal scale line along the bottom k#=woffset ;work from the grid center backwards i=0 While k#>=width0 ;continue while display area remains If h#<=width Then ;don't display if still out of view area Line k#,height-45,k#,height-35 ;make a tick mark on the horizontal scale line Locate k#-5,height-35 ;position to write the tick mark value Write Str$(i) ;write the tick mark value EndIf k#=k#-j# ;decrement the amount to the next tick mark i=i-10 ;decrement the tick count by ten Wend k#=woffset+j# ;start at the tick position right of center i=10 ;start with a tick count of ten While k#<=width ;continue across the viewable area If k#>=width0 Then ;don't bother with line if out of viewable area Line k#,height-45,k#,height-35 ;draw the tick mark indicated Locate k#-5,height-35 ;position to write the tick mark value Write Str$(i) ;write the tick mark value EndIf k#=k#+j# ;increment the tick mark offset position i=i+10 ;increment the tick mark count by 10 Wend Line width-20,height0+20,width-20,height-35 ;draw the right side vertical scale line k#=hoffset ;begin at the center crosshairs i=0 ;set the tick count to zero While k#>=height0+30 ;don't mess up the equation text area If k#<height Then ;don't draw line if not in viewable area Line width-35,k#,width-20,k# ;draw a tick mark against the vertical scale line n$=Str$(i) ;create the text for the tick count value Locate width-Len(n$)*8+5*(i<0),k#-5 ;position to write the tick count value Write n$ ;write the tick count value EndIf k#=k#-j# ;decrement the tick mark offset position i=i-10 ;decrement the tick mark count by 10 Wend k#=hoffset+j# ;start at one tick mark below crosshairs i=10 ;start with a count of ten While k#<=height-30 ;continue until out of viewable area If k#>=height0 Then ;delay line if not yet in viewable area Line width-35,k#,width-20,k# ;draw tick mark up to vertical scale line n$=Str$(i) ;get tick mark count Locate width-Len(n$)*8+5,k#-5 ;position to write tick mark count Write Str$(i) ;write tick mark count EndIf k#=k#+j# ;increment tick mark position i=i+10 ;increment tick mark count by 10 Wend EndIf xlen=1000*zoom ;we arbitrarily make the cross hairs 1000 long Color 128,255,128 ;make the crosshairs the color of green Line woffset-xlen,hoffset,woffset+xlen,hoffset ;paint the horizontal crosshair first Line woffset,hoffset-xlen,woffset,hoffset+xlen ;paint the vertical crosshair second Color 255,255,255 ;set the current color to bright white End Function |
| ||
The program above was a first attempt. I have since made many changes and extended it, and the new version (without the parabolic code) has now been added to the Code Archives under 2D Graphics with the name X-Y 2D Graphs. I put code in it to draw two random straight line segments, fine their equations, then use Cramer's Rule with some limits to find out if the lines segments, as plotted, intersect. Note that computers do not see things as humans do, and while I could draw a couple of lines on any surface and tell from looking at them if they intersect, computers are not equipped to see and make this type of determination. For computers, you end up with having to deal with equations, coordinates, bit-maps (such as from scanners), or vectors as a rule. This program allows you to begin to bridge the gap between what computers can be programmed to do, and what comes naturally to humans, or can be learned in terms of describing the world around us. |