Spring in the Northern Hemisphere is a lovely time.
I just happened to notice, for the first time in 70 years, that wood anemones don't always have the same number of petals- usually 6 or 7, but sometimes 5 or 8. I'm a bit obsessive/compulsive at times....
I thought it'd be fun to make some programmatic flowers. I started by writing a routine to draw ellipses, fill them and display them rotated and centred wherever I wished. This is easier than using the turtle 'ellipse' option, and I had no great need for speed. At this point I got a bit carried away, and lots of nice patterns resulted.
Now I got back on track and created the petal arrangement.
Lots more things to play with- spiralling petals of increasing size for instance.
LB makes this kind of flight-of-fancy very easy.
=
' ************************************************************************** ' *** ** ' *** filledShapesNonTurtle4c 5 Jun 2016 tenochtitlanuk ** ' *** ** ' ************************************************************************** ' Demonstrates turtle drawn directly, avoiding LB's turtle errors and giving ' direct access to turtle's position/heading, saved in global TX, TY, Ttheta. ' Also demonstrates colour-filling. Shape outlines are drawn in a colour ' differing by +1 in RGB components. 1 in 2^24 chance it's already in use! ' The first argument for ExtFloodFill is the handle for the graphicbox device contest. ' The x and y location to begin the fill are the next arguments. ' These coordinates are counted from the upper left corner of the graphics area. ' The arguments for color and fill type are next. ' With _FLOODFILLBORDER ( =0) type of fill, the fill area is bounded by the color specified by the crColor parameter. ' With _FLOODFILLSURFACE ( =1) type of fill, the fill area is defined by the color that is specified by crColor. ' Filling continues outward in all directions as long as the color is encountered. ' NB Fills from a centre within shape, which must be therefore on-screen. nomainwin global pi, TX, TY, Ttheta, wFillType, hdc TX =400: TY =350: Ttheta =0 ' screen centre, pointing North/up. pi =4 *atn( 1) ' n step turn .......... shape$ ="4, 0.5, 150, 1, 120, 1, 120, 1, -60" ' equilateral triangle, apex up. 'add an 'R' flag if figure is a loop of identical step/turns?? WindowWidth =750: WindowHeight =740 ' width 1150 if enable the textwindow for diagnostics graphicbox #w.gb, 10, 10, 804, 704 'texteditor #w.te, 820, 10, 320, 700 menu #w, "File", "Save", [save] open "Demo. of Filled Shapes & improved Turtle." for window as #w #w "trapclose quit" #w.gb "down ; fill 80 80 80 ; color cyan" '#w.te "!font courier 16" h = hwnd( #w.gb) calldll #user32, "GetDC", h as ulong, hdc as ulong wFillType =0 'call graticule #w.gb "flush ; up ; size 1" '#w.te " Now at " +using( "####", TX) +using( "####", TY) +" & facing " + using( "####.#", Ttheta) ra =300 for angle =0 to 360 *8 step 27 ra =200 -angle /360 /10 *150 x =400 +int( ra *cosRad( angle)) y =350 +int( ra *sinRad( angle)) w = 40 ' int( ( 4 *360 -angle) /360 /4 *40) h =int( ( 10 *360 -angle) /360 /10 *160) call ellipse x, y, w, h, angle, int( 254 -angle /50), int( 254 -angle /50), 0 'call delay 1000 next angle wait '#w.te " Now at "+ using( "####", TX) +using( "####", TY) +" & facing " + using( "####.#", Ttheta) #w.gb "flush" wait function MakeRGB( red, green, blue) if red < 0 then red = 0 if red >255 then red =255 if green < 0 then green = 0 if green >255 then green =255 if blue < 0 then blue = 0 if blue >255 then blue =255 MakeRGB =( blue *256 *256) +( green *256) +red end function function sinRad( a) sinRad =sin( a *pi /180) end function function cosRad( a) cosRad =cos( a *pi /180) end function sub draw lifted, x, y if lifted =0 then #w.gb "up" else #w.gb "down" #w.gb "line "; TX; " "; TY; " "; x; " "; y Ttheta =atan2( x -TX, TY -y) *180 /pi ' NB DEGREES. TX =x TY =y end sub sub turn angle ' increment/update global turtle direction ( in DEGREES) Ttheta =( Ttheta +angle) mod 360 end sub sub forward s dx =s *cosRad( Ttheta) dy =s *sinRad( Ttheta) #w.gb "down ; line "; TX; " "; TY; " "; TX +dx; " "; TY +dy; " ; up" TX =TX +dx TY =TY +dy end sub function atan2( x, y) Result$ = "Undetermined" If ( x = 0) and ( y > 0) Then atan2 = pi / 2: Result$ = "Determined" If ( x = 0) and ( y < 0) Then atan2 = 3 * pi / 2: Result$ = "Determined" If ( x > 0) and ( y = 0) Then atan2 = 0: Result$ = "Determined" If ( x < 0) and ( y = 0) Then atan2 = pi: Result$ = "Determined" If Result$ = "Determined" Then [End.of.function] BaseAngle = Atn( abs( y) /abs( x)) If (x > 0) and (y > 0) Then atan2 = BaseAngle If (x < 0) and (y > 0) Then atan2 = pi -BaseAngle If (x < 0) and (y < 0) Then atan2 = pi +BaseAngle If (x > 0) and (y < 0) Then atan2 = 2*pi -BaseAngle [End.of.function] end function sub graticule for x =0 to 800 step 100 ' draw vertical graticule lines #w.gb "line "; x; " "; 0; " "; x; " "; 700 next x for y =0 to 700 step 100 #w.gb "line "; 0; " "; y; " "; 800; " "; y next y end sub [save] #w.gb "getbmp scr 0 0 800 700" filedialog "Save as ", "*.bmp", fn$ bmpsave "scr", fn$ wait sub quit h$ close #h$ calldll #user32, "ReleaseDC", hw as ulong, hdc as ulong 'release the DC end end sub ' _________________________________________ sub ellipse x, y, Major, Minor, inclination, R, G, B crColor =MakeRGB( R, G, B) xx =Minor *cosRad( 0) yy =Major *sinRad( 0) xs =x +xx *cosRad( inclination) -yy *sinRad( inclination) ys =y +xx *sinRad( inclination) +yy *cosRad( inclination) #w.gb "goto "; xs; " "; ys #w.gb "down" #w.gb "color "; R; " "; G; " "; B ' targetcolour R G B #w.gb "backcolor "; R +1; " "; G +1; " "; B +1 ' visibly same, but distinguished by ExtFloodFill as boundary. -fillcolour R+1 G+1 B+1 for angle =0 to 370 step 10 xx =Minor *cosRad( angle) yy =Major *sinRad( angle) xs =x +xx *cosRad( inclination) -yy *sinRad( inclination) ys =y +xx *sinRad( inclination) +yy *cosRad( inclination) #w.gb "goto "; xs; " "; ys next angle #w.gb "color red ; size 5 ; set "; x; " "; y; " ; size 1" 'call delay 1000 'goto [noFill] calldll #gdi32, "ExtFloodFill",_ hdc As uLong,_ 'device context x As Long,_ 'x location to start filling y As Long,_ 'y location to start filling crColor As Long,_ 'long colour value of border, or colour to replace wFillType As Long,_ 'flag for type of fill result As Long 'nonzero if successful [noFill] #w.gb "up" end sub '1 2 3 4 5 6 7 .. sub display shape$, scale, col$, x, y, angle ' shape$ ="4, 0.5,150, 1,120, 1,120, 1,120, 1, 150" noOfTerms =val( word$( shape$, 1, ",")) #w.gb "color "; col$ #w.gb "north" #w.gb "up ; goto "; x ; " "; y #w.gb "turn "; angle vStep =val( word$( shape$, 2, ",")) *scale #w.gb "go "; vStep: print "up ; go "; vStep vAngle =val( word$( shape$, 3, ",")) #w.gb "turn "; vAngle: print "turn "; vAngle #w.gb "down": print "down" for i =1 to noOfTerms +1 vStep =val( word$( shape$, 2 *i +2, ",")) *scale vAngle =val( word$( shape$, 2 *i +3, ",")) #w.gb "go "; vStep #w.gb "turn "; vAngle print "go "; vStep; " ; turn "; vAngle next i call delay 1000 end sub sub delay t timer t, [cont] wait [cont] timer 0 end sub ' from here is spare, now redundant code 'side =20 'for i =1 to 10 'R =int( 255 *rnd( 1)): G =int( 255 *rnd( 1)): B =int( 255 *rnd( 1))' RGB never =255... 'crColor =MakeRGB( R, G, B) 'x =400: y =350 '#w.gb "color "; R; " "; G; " "; B ' targetcolour R G B 'call delay 1000 call display shape$, 400 -30 *i, str$( R) +" " +str$( G) +" " +str$( B), x, y, i *3 ' here, a single call. 'rMa =int( 10 +100 *rnd( 1)): rMi =int( 10 +100 *rnd( 1)): inclination =int( 0 + 90 *rnd( 1)) 'call ellipse x, y, rMa, rMi, inclination '#w.gb "backcolor "; R +1; " "; G +1; " "; B +1 ' visibly same, but distinguished by ExtFloodFill as boundary. -fillcolour R+1 G+1 B+1 'call delay 1000 'calldll #gdi32, "ExtFloodFill",_ 'hdc As uLong,_ 'device context 'x As Long,_ 'x location to start filling 'y As Long,_ 'y location to start filling 'crColor As Long,_ 'long colour value of border, or colour to replace 'wFillType As Long,_ 'flag for type of fill 'result As Long 'nonzero if successful 'next i