From 0ec666c9e24041976321c455a84fb5de3de8a5df Mon Sep 17 00:00:00 2001 From: d6 Date: Fri, 5 May 2023 14:05:50 -0400 Subject: [PATCH] improve graphing a bit --- graph.tal | 118 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 34 deletions(-) diff --git a/graph.tal b/graph.tal index b9fef6d..3cfa926 100644 --- a/graph.tal +++ b/graph.tal @@ -25,46 +25,72 @@ |20 @Screen &vect $2 &w $2 &h $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 |0000 + ( set up variables used to configure graphing ) + @width $2 ( screen width in pixels ) + @height $2 ( screen height in pixels ) @epsilon $2 ( graph value per pixel ) - @xmin $2 ( min x graph coord ) @xmax $2 ( max x graph coord ) @ymin $2 ( min y graph coord ) @ymax $2 ( max y graph coord ) + ( we really want (xmax-xmin)*epsilon to exactly equal width ) + ( and similarly (ymax-ymin)*epsilon to exactly equal height ) + ( ) + ( this implies a square screen. for non-square screens we'll ) + ( need separate epsilons for x and y. ) + ( ) + + ( variables used during graphing ) @step $2 ( current step size for drawing ) - - @expr $2 - + @expr $2 ( current equation being graphed ) @x0 $2 ( lower bound of x ) @x1 $2 ( upper bound of x ) @y0 $2 ( lower bound of y ) @y1 $2 ( upper bound of y ) |0100 + ( screen size ) + #0200 .width STZ2 + #0200 .height STZ2 + ( colors ) #0f0f .System/r DEO2 #0ff0 .System/g DEO2 #00ff .System/b DEO2 - ( default settings ) - #0004 .epsilon STZ2 ( 0.004 ) - #fc00 .xmin STZ2 ( -4.0 ) - #0400 .xmax STZ2 ( +4.0 ) - #fc00 .ymin STZ2 ( -4.0 ) - #03fc .ymax STZ2 ( +4.0 - epsilon ) + ( set up screen device ) + .width LDZ2 .Screen/w DEO2 + .height LDZ2 .Screen/h DEO2 - ( h = w = 0x200 = 512 ) - .xmax LDZ2 .xmin LDZ2 SUB2 .epsilon LDZ2 DIV2 .Screen/w DEO2 - .ymax LDZ2 .ymin LDZ2 SUB2 .epsilon LDZ2 DIV2 .Screen/h DEO2 + ( default settings: -4.0 to +4.0 ) +( #fc00 DUP2 .xmin STZ2 .ymin STZ2 + #0400 DUP2 .xmax STZ2 .ymax STZ2 ) + #0400 + DUP2 .xmax STZ2 DUP2 .ymax STZ2 + #0000 SWP2 SUB2 + DUP2 .xmin STZ2 .ymin STZ2 + + ( TODO: we probably want separate epsilons for x and y ) + ( TODO: validate that (xmax-xmin)*eps = width exactly ) + x-range .width LDZ2 DIV2 .epsilon STZ2 + + ( draw x and y axis on background ) + draw-y-axis draw-x-axis + + ( prepare equation ) ;x^3-2x+1 .expr STZ2 +( ;0.5x^2-6 .expr STZ2 ) - draw-border + ( set up starting parameters ) + .xmin LDZ2 .ymin LDZ2 x-range - .xmin LDZ2 .ymin LDZ2 #0800 draw + ( graph the equation ) + draw BRK - BRK +@x-range ( -> x-range* ) .xmax LDZ2 .xmin LDZ2 SUB2 JMP2r +@y-range ( -> y-range* ) .ymax LDZ2 .ymin LDZ2 SUB2 JMP2r @hline ( x1* x2* y* ) #01 .Screen/auto DEO .Screen/y DEO2 OVR2 .Screen/x DEO2 @@ -74,24 +100,40 @@ #02 .Screen/auto DEO .Screen/x DEO2 OVR2 .Screen/y DEO2 SUB2 &yloop #02 .Screen/pixel DEO INC2 ORAk ?&yloop POP2 JMP2r -@draw-border - #0000 #0200 #0100 vline - #0000 #0200 #0100 hline +@center-x ( -> cx* ) .width LDZ2 #01 SFT2 JMP2r +@center-y ( -> cx* ) .height LDZ2 #01 SFT2 JMP2r - #00f0 #0110 #0040 vline - #00f0 #0110 #0080 vline - #00f0 #0110 #00c0 vline - #00f0 #0110 #0140 vline - #00f0 #0110 #0180 vline - #00f0 #0110 #01c0 vline +( TODO: gets weird with non-powers-of-2 ) +@draw-y-axis ( -> ) + #0000 .height LDZ2 center-x vline ( ) + center-x #0010 SUB2k ,&lmid STR2 ( ) + ADD2 ,&rmid STR2 ( ) + .height LDZ2 STH2 ( [h*] ) + #0100 .epsilon LDZ2 DIV2 ,&vstep STR2 ( [h*] ) + ,&vstep LDR2 STH2 ( [h* step*] ) + &vloop ( [h* pos*] ) + [ LIT2 &lmid $2 ] ( lmid* [h* pos*] ) + [ LIT2 &rmid $2 ] ( lmid* rmid* [h* pos*] ) + STH2kr vline ( [h* pos*] ) + [ LIT2r &vstep $2 ] ADD2r ( [h* pos+step*] ) + GTH2kr STHr ?&vloop ( [h* pos+step*] ) + POP2r POP2r JMP2r ( ) - #00f0 #0110 #0040 hline - #00f0 #0110 #0080 hline - #00f0 #0110 #00c0 hline - #00f0 #0110 #0140 hline - #00f0 #0110 #0180 hline - #00f0 #0110 #01c0 hline - JMP2r +( TODO: gets weird with non-powers-of-2 ) +@draw-x-axis ( -> ) + #0000 .width LDZ2 center-y hline ( ) + center-y #0010 SUB2k ,&lmid STR2 ( ) + ADD2 ,&rmid STR2 ( ) + .width LDZ2 STH2 ( [w*] ) + #0100 .epsilon LDZ2 DIV2 ,&hstep STR2 ( [w*] ) + ,&hstep LDR2 STH2 ( [h* step*] ) + &hloop ( [w* pos*] ) + [ LIT2 &lmid $2 ] ( lmid* [w* pos*] ) + [ LIT2 &rmid $2 ] ( lmid* rmid* [w* pos*] ) + STH2kr hline ( [w* pos*] ) + [ LIT2r &hstep $2 ] ADD2r ( [w* pos+step*] ) + GTH2kr STHr ?&hloop ( [w* pos+step*] ) + POP2r POP2r JMP2r ( ) ( recursive drawing procedure ) ( ) @@ -106,6 +148,7 @@ POP2 POP2 POP2r JMP2r ( ; miss ) &hit ( x* y* [s*] ) STH2kr #0001 EQU2 ?&term ( x* y* [s*] ) +( STH2kr .epsilon LDZ2 LTH2 ?&term ( x* y* [s*] ) ) LITr 01 SFT2r ( x* y* [h=s/2*] ) OVR2 OVR2 ( x* y* x* y* h* [h*] ) STH2kr draw ( x* y* [h*] ; south west ) @@ -119,12 +162,13 @@ &term ( x* y* [s*] ) POP2r ( x* y* ) .ymax LDZ2 SWP2 SUB2 ( x* ymax-y* ) - .epsilon LDZ2 DIV2 ( x* sy=(ymax-y)/e* ) + .epsilon LDZ2 SUB2 ( x* ymax-y-e* ) + .epsilon LDZ2 DIV2 ( x* sy=(ymax-y-e)/e* ) .Screen/y DEO2 ( x* ; screen/y<-sy ) .xmin LDZ2 SUB2 ( x-xmin* ) .epsilon LDZ2 DIV2 ( x* sx=(x-xmin)/e* ) .Screen/x DEO2 ( ; screen/x<-sx ) - #41 .Screen/pixel DEO ( ; screen/pixel<-40 ) + #41 .Screen/pixel DEO ( ; screen/pixel<-41 ) JMP2r ( ) ( determine if the given x and y intervals intersect ) @@ -187,6 +231,12 @@ STH2k INC2 STA2 ( [addr*] ; addr+1<-e0* ) STH2r JMP2r ( addr* ) +@0.5x^2-6 05 =0.5x^2 =six +@0.5x^2 06 =x^2 =0.5 +@x^2 03 =x 02 +@0.5 01 0080 +@six 01 0600 + @x^3-2x+1 04 =x^3-2x =one @x^3-2x 05 =x^3 =2x @one 01 0100