\ AN-cirkel 2026-09-29 wj: plot een cirkel met alleen optellen en aftrekken
\ Getest met (en deels afhankelijk van) gforth 0.7.3
\ zie cirkel-opgave-an.pdf:
\ berekening van de afwijkingen van x^2+y^2 tov r^2 voor het plotten van een
\ cirkel

\ gegeven: we plotten op een cartesiaans coördinatenstelsel x y een cirkel met
\ straal r
\ Uitgangspunt is het berekenen van de afwijkingen startend vanaf x=0 y=r en
\ eindigend bij de 45 graden lijn x=y
\ Beginpunt is x = 0, y = r, de volgorde is:
\ 1. bepaal de afwijking van de huidige positie
\ 2. plot positie en bepaal afwijking-oost en afwijking-zuid t.o.v.huidige
\    positie
\ 3. bepaal richting afhankelijk van afwijking-oost en afwijking-zuidoost:
\ 4. als afwijking-zuidoost abs groter is: oost (eerst afwijking-oost naar
\    afwijking, daarna x aanpassen)
\ 5. in alle andere gevallen twee stappen: oost gevolgd door zuid (eerst
\    afwijking-zuid naar afwijking, dan y aanpassen)
\ 6. stop wanneer x = y of x + 1 = y (heeft te maken met oneven of even stappen
\    nodig) en plot eindpositie
\ 7. verder naar 2.
\ Merk op dat de circel lijn eindigt met een hoek van 90 graden op de 45
\ graden lijn en dat er dus voor het eerste octant nooit twee of meer stappen
\ naar het zuiden nodig zijn, het is altijd 1 of 0 stappen naar het zuiden
variable x-w \ x waarde
variable y-w
variable afwijking

\ oost: nieuwe afwijking = afwijking + (x + x + 1)
: afwijking-oost ( -- n ) afwijking @  x-w @ dup 1+ +  + ;
\ zuidoost: nieuwe afwijking = afwijking - (y + y - 1)
: afwijking-zuidoost ( -- n ) afwijking-oost   y-w @ dup 1- +  - ;

\ cirkel loopt van -r tot r, scherm coordinaten hebben alleen positieve
\ getallen, dus: bepaal het midden van het scherm (form geeft lengte en breedte
\ van het scherm in tekens:
: x-mid ( -- n )  form nip 2 / ;
: y-mid ( -- n )  form drop 2 / ;
\ begrens r tot maximum wat op het scherm past:
: r-begrenzing ( r -- r' )  x-mid y-mid min min ;

\ we berekenen een octant, dus we moeten elk punt 8 keer plotten voor een hele
\ cirkel

\ zet de oorsprong (x=0, y=0) in het midden van het scherm en corrigeer (2 *)
\ voor de omvang van de tekens, die zijn smal (zonder correctie krijgen we een
\ ovaal, met correctie bijna een cirkel):
: 1plot ( y x -- )  2 * x-mid +  swap y-mid + at-xy '* emit ;
\ negate is spiegelen om de x of y as, of beide:
: 4plot ( x y -- )
    2dup 1plot
    2dup negate 1plot
    2dup swap negate swap 1plot
    negate swap negate swap 1plot ;
: 8plot ( y x x y -- )  4plot 4plot ; \ wel en niet gespiegeld
\ x y swap is spiegelen om lijn y=x, dus 45 graden lijn:
: plot ( y x -- ) 2dup swap 8plot 100 ms ;

\ verplaats in het coordinaten systeem
: ga-oost ( -- )  x-w dup @ 1+ swap ! ;
: ga-zuid ( -- )  y-w dup @ 1- swap ! ;
: ga-zuidoost ( -- ) ga-zuid ga-oost ;

: plot-cirkel ( n.r -- )
    r-begrenzing   y-w !   0 x-w !   0 afwijking ! \ zie 1. hierboven
    begin y-w @ x-w @ plot \ 2.
        afwijking-zuidoost abs
        afwijking-oost abs  > if \ 3.
        afwijking-oost afwijking ! ga-oost \ 4.
    else
        afwijking-zuidoost afwijking ! ga-zuidoost \ 5.
    then
    x-w @ y-w @ =  x-w @ 1+ y-w @ =  or  until \ 6. en 7.
    y-w @ x-w @ plot 0 0 at-xy  2000 ms ;

page
\ 0 plot-cirkel 1 plot-cirkel \ singulariteit!
2 plot-cirkel 3 plot-cirkel 5 plot-cirkel 7 plot-cirkel 9 plot-cirkel 11 plot-cirkel 15 plot-cirkel
20 plot-cirkel 30 plot-cirkel

bye

\ set tw=80
