Liberty BASIC Community Forum
Special Topics and Projects >> Contests >> Paper Snowflake
http://libertybasic.conforums.com/index.cgi?board=contests&action=display&num=1448459716

Paper Snowflake
Post by tsh73 on Nov 25th, 2015, 07:55am

Hello, everyone
Winter is in, Christmas is near, so we start a little challenge.

The theme is "paper snowflake".
Remember folding paper, folding it again, and again - and start cutting like mad B)?
Well, if you don't, google for "paper snowflake".
It gives many beautiful designs.

Apparently running with scissors is dangerous - but programming with LB is not! And "turn 60" instruction looks created for drawing snowflakes.

So the task obviously is to make a program that will draw similar design(s). Besides that -
* You can make single beautiful snowflake.
* Or make it came different each time you run the program.
* Or make it animated (Grow? Rotate? Fall down?).
* Make whole snowfall! (hint: sprites?)
* Or allow user to draw part of it (simulate scissors?) and draw it in full.
* insert you great idea here

- there too many different ways to have fun with it.

I suggest time frame is from here to Christmas.

Here's something to get you started:
Code:
nomainwin
open "Paper Snowflake" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "fill black; down; color white"
#gr "size 15"

a=0
' repeat 6 times
for i = 1 to 6
    #gr "home; north; turn ";a
    'draw single "arm" from center
    #gr "go 70"
    #gr "turn 60"
    #gr "go 40"
    #gr "go -40"    'you can go back like this
    #gr "turn -120"
    #gr "go 40"
    #gr "go -40"
    #gr "turn 60"   'make sure drawing direction is aligned right then you draw further
    #gr "go 40"
    a=a+60  'each arm turned 60 degrees more
next

#gr "flush"
wait

[quit]
close #gr
 


You may say:
"Hey, this doesn't look like paper snowflake!"
Well, go ahead and make better one!
Re: Paper Snowflake
Post by Alyce Watson on Nov 25th, 2015, 11:39am

The example is unbelievably cool! (No pun intended.) What a tiny amount of code to produce something so fantastic. I love this, Anatoly.
Re: Paper Snowflake
Post by tenochtitlanuk on Nov 25th, 2015, 2:26pm

A quick modification of Carl's 'simplest ever drawing program' in the Help files.
You use the mouse to draw in the active sector. The line is mirrored everywhere else..
User Image - User Image
It is easy to print or save the screen. It helps to add colour fills. Closely related to kaleidoscopes- why not add a colour selector/brush size change?
User Image
It is rather too easy to leave small gaps at present. Change to drawing straight lines from previous click would be easy. Have fun!! ( and if American, don't celebrate too hard your thankfulness for getting successfully away from the 'Old World')

Code:
  nomainwin

  WindowWidth  =600
  WindowHeight =600

  open "Paint your star!" for graphics_nsb as #w

  #w "trapclose [quit]"
  #w "when leftButtonMove [paint]"
  #w "color 180 180 180 ; backcolor 240 240 160 ; goto 300 300 ; down ; set 300 300 ; circle 250 ; piefilled 500 500 0 -30 ; size 2"
  #w "color black"
  wait

[paint]
  x       =MouseX -300
  y       =300 -MouseY
  radius  =( x^2 +y^2)^0.5
  theta   =180 /3.14159265 *atan2( y, x)
  if theta >30 or theta <0 or radius <30 or radius >250 then wait
  call set radius,   0 +theta
  call set radius,   0 -theta
  call set radius,  60 -theta
  call set radius,  60 +theta
  call set radius, 120 -theta
  call set radius, 120 +theta
  call set radius, 180 +theta
  call set radius, 180 -theta
  call set radius, 240 -theta
  call set radius, 240 +theta
  call set radius, 300 -theta
  call set radius, 300 +theta

  wait

sub set r, t
    if r <250 then
        t =t *3.14159265 /180
        x =300 +r *cos( t)
        y =300 +r *sin( t)
        #w "set "; x; " "; y
    end if
end sub

[quit]
  close #w
  end

function atan2( y, x)
    pi =atn( 1) *4
    if x <>0 then arctan = atn( y /x)
    select case
        case x >0
            atan2 =arctan
        case y >=0 and x <0
            atan2 =pi +arctan
        case y <0 and x <0
            atan2 =arctan -pi
        case y >0 and x =0
            atan2 =pi /2
        case y <0 and x =0
            atan2 =pi /-2
    end select
end function
 

Re: Paper Snowflake
Post by CarlGundel on Nov 25th, 2015, 9:42pm

Very cool stuff!

-Carl
Re: Paper Snowflake
Post by tenochtitlanuk on Nov 26th, 2015, 4:36pm

Or, with the vector approach, I got various fun images-with-stars. It's a 2M download, and to see the animation again you may have to <Shift><Refresh> or similar.
User Image

Will pull my attempts together on my web site when I have time!
Re: Paper Snowflake
Post by tenochtitlanuk on Nov 29th, 2015, 06:44am

Another version! Based on the Koch Snowflake.
User Image

User Image - User Image
Creating this reminded me of the problem when the turtle 'go's a non-integral distance- it goes by the rounded-down step.
User Image
As a result my first attempts kept producing figures that were distorted or did not 'close' because of the rounding problem. But the code below shows how closely the program follows the algorithm..
User Image
Code:
nomainwin

WindowWidth  =800: WindowHeight =700

graphicbox #w.gb, 0,0,800,700

open "Demo Koch Snowflake" for window as #w

#w    "trapclose quit"
#w.gb "color black ; goto 200 500 ; north ; down ; size 2"

d =2

for i =1 to 1'5
    x = 50 +100 *i
    y =150 +100 *i
    #w.gb "up ; goto "; x; " "; y; " ; north ; down"

    r =int( 50 +250 *rnd( 1))
    #w.gb "color black"'; r; " 0 "; 255 -r

    l =int( 200 -i *10)

    for side =1 to 3
        call f l, d
        #w.gb "turn 120"
    next side

    #w.gb "color red ; backcolor "; r; " 0 "; 255 -r
    targetcolor =0

next i

wait

sub quit h$
    close #h$
    calldll #user32, "ReleaseDC", hw as ulong, hdc as ulong   'release the DC
    end
end sub

sub f length, depth
   scan
   if depth <= 0 then
     #w.gb "go "; int( length)
   else
     call f length /3, depth -1:     #w.gb "turn -60"
     call f length /3, depth -1:     #w.gb "turn 120"
     call f length /3, depth -1:     #w.gb "turn -60"
     call f length /3, depth -1
   end if
end sub
 

I found it easiest to avoid the 'go' by saving turtle location as x/y floats, but you could instead add 0.5 to all 'go' commands so they round off better..

Re: Paper Snowflake
Post by Alyce Watson on Nov 29th, 2015, 08:14am

Truly fascinating stuff!

Anatoly and John are both teachers. What fun your classes must be! (Or must have been!). wink
Re: Paper Snowflake
Post by tsh73 on Nov 29th, 2015, 08:48am

Quote:
Anatoly and John are both teachers.

You just blew our cover!
*ROTFL*

EDIT
quoter from my colleague:
"You should not annoy me, your teacher [that much]. If I bite you you will became teachers yourself!"
(No, I wasn't bitten by a teacher in my youth. Or was I? How could I be sure?!)
Re: Paper Snowflake
Post by Joseph on Nov 30th, 2015, 05:05am

Wow, this is incredible. Good job, guys!
Re: Paper Snowflake
Post by Alyce Watson on Dec 1st, 2015, 04:52am

on Nov 29th, 2015, 08:48am, tsh73 wrote:
You just blew our cover!
*ROTFL*

EDIT
quoter from my colleague:
"You should not annoy me, your teacher [that much]. If I bite you you will became teachers yourself!"
(No, I wasn't bitten by a teacher in my youth. Or was I? How could I be sure?!)


Anatoly, as we say in the US, "It takes one to know one." (Retired teacher, here. wink )

This challenge has spawned imaginative graphics programs, both on this thread and on the graphics board. Thanks so much for creating it!

Re: Paper Snowflake
Post by tsh73 on Dec 1st, 2015, 05:14am

Quote:
as we say in the US, "It takes one to know one."

Russian is "Fisherman recognizes other Fishermen from afar"
(versed as
rybak rybaka
vidit izdaleka
)
EDIT proverbs could not be translated 100% accurately
sad
Layers of meaning and history makes that impossible.
Re: Paper Snowflake
Post by tenochtitlanuk on Dec 1st, 2015, 08:30am

...and it so happens my surname is 'Fisher'!!
Like Russians, we have lots of names like Smith (Kuznetsov) that come from ancient occupations, but don't have patronymics. That we can compare proverbs is a bit like 'convergence' in evolution. We're all the same 'under the skin'.
Re: Paper Snowflake
Post by tsh73 on Dec 10th, 2015, 2:14pm

What? No takers?
Here is modification of first one - when I'll need bunch of flakes I'll use this...
Code:
nomainwin
open "Paper Snowflake" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "fill black; down; color white"
#gr "size 10"

a=0
' repeat 6 times
for i = 1 to 6
    #gr "home; north; turn ";a
    'draw single "arm" from center
    #gr "go 40"
    #gr "turn 120"
    #gr "go 40"
    #gr "go -40"    'you can go back like this
    #gr "turn -240"
    #gr "go 40"
    #gr "go -40"
    #gr "turn 120"
    #gr "go 40"
    #gr "turn 60"
    #gr "go 40"
    #gr "go -40"    'you can go back like this
    #gr "turn -120"
    #gr "go 40"
    #gr "go -40"
    #gr "turn 60"   'make sure drawing direction is aligned right then you draw further
    #gr "go 40"
    a=a+60  'each arm turned 60 degrees more
next

#gr "flush"
wait

[quit]
close #gr
 

and nice recursive one
Code:
nomainwin
open "Paper Snowflake" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "fill black; down; color white"
'#gr "size 15"
#gr "home; posxy cx cy"

call flake cx, cy, 100

#gr "flush"
wait

sub flake cx, cy, r
    if r <1 then exit sub
    ' repeat 6 times
    for i = 0 to 5
        #gr "place ";cx;" ";cy
        #gr "north; turn ";i*60 'recustion breaks current angle, so had to start with North each time
        #gr "go ";r
        #gr "posxy cx1 cy1"
        call flake cx1, cy1, r/3
    next
end sub

[quit]
    close #gr
 

Re: Paper Snowflake
Post by tsh73 on Dec 10th, 2015, 2:54pm

Quote:
>>when I'll need bunch of flakes

Yeah.
Problems:
1) it takes a lot of CPU - I better use sprites
2) XOR doesn't work with "go 40; go -40" kind of thing
3) they scale really weird :(
Code:
nomainwin
gosub [getSlack]

h=400
w=600
WindowHeight=h+slackY
WindowWidth =w+slackX

UpperLeftX = (DisplayWidth-WindowWidth)/2
UpperLeftY = (DisplayHeight-WindowHeight)/2

open "Snow Lissajous" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "down; fill black"
#gr "backcolor black"
#gr "color white"

'call flake 150,150,30
'wait

t=0
dt=0.02
a=7
b=6
n=15
#gr "rule ";_R2_XORPEN
dim x(n), y(n)
timer 150, [nxt]
while 1
    for i = 0 to n
        'draw
        if t >0 then 'clear prevoius
            x=w/2.2*cos(a*(t+i*dt-dt))+w/2
            y=h/2.2*sin(b*(t+i*dt-dt))+h/2
            call flake int(x),int(y),i*1.5
        end if
        'clear with XOR
        x=w/2.2*cos(a*(t+i*dt))+w/2
        y=h/2.2*sin(b*(t+i*dt))+h/2
        call flake int(x),int(y),i*1.5
    next
    wait
[nxt]
    'change t
    t=t+dt
    #gr "discard"
    '#gr "fill black"
wend

#gr "flush"


wait

[quit]
    timer 0
    close #gr
end

[getSlack]
    WindowWidth=200:WindowHeight=200
    open "" for graphics_nsb as #t:#t,"home;posxy x y":close#t
    slackX=WindowWidth-2*x:slackY=WindowHeight-2*y
return

sub flake x0,y0,rr
'#gr "color black"
'#gr "place ";x0;" ";y0;"; circlefilled "; rr+2
'#gr "color white"
a=0
r=int(rr/3)
' repeat 6 times
for i = 1 to 6
    #gr "place ";x0;" ";y0
    #gr "north; turn ";a
    'draw single "arm" from center
    #gr "go ";r
    #gr "posxy x y" 'store point
    #gr "turn 120"
    #gr "go ";r
    #gr "place ";x;" ";y    'restore point
    #gr "turn -120"
    #gr "go ";r
    #gr "posxy x y" 'store point
    #gr "turn 60"
    #gr "go ";r
    #gr "place ";x;" ";y    'restore point
    #gr "turn -120"
    #gr "go ";r
    #gr "place ";x;" ";y    'restore point
    #gr "turn 60"   'make sure drawing direction is aligned right then you draw further
    #gr "go ";r
    a=a+60  'each arm turned 60 degrees more
next
end sub
 

Re: Paper Snowflake
Post by tsh73 on Dec 11th, 2015, 07:30am

better scaling
Code:
nomainwin
gosub [getSlack]

h=400
w=600
WindowHeight=h+slackY
WindowWidth =w+slackX

UpperLeftX = (DisplayWidth-WindowWidth)/2
UpperLeftY = (DisplayHeight-WindowHeight)/2

open "Snow Lissajous" for graphics_nsb_nf as #gr
#gr "trapclose [quit]"
#gr "down; fill black"
#gr "backcolor black"
#gr "color white"
#gr "rule ";_R2_XORPEN

'for i = 1 to 15
'    call flake 20+(15-i)*40,150,i*1.5
'next
'for i = 1 to 15
'    call flake2 20+(15-i)*40,200,i*1.5
'next
'#gr "flush"
'wait

t=0
dt=0.02
a=7
b=6
n=15
dim x(n), y(n)
timer 150, [nxt]
while 1
    for i = 0 to n
        'draw
        if t >0 then 'clear prevoius
            x=w/2.2*cos(a*(t+i*dt-dt))+w/2
            y=h/2.2*sin(b*(t+i*dt-dt))+h/2
            call flake int(x),int(y),i*1.5
        end if
        'clear with XOR
        x=w/2.2*cos(a*(t+i*dt))+w/2
        y=h/2.2*sin(b*(t+i*dt))+h/2
        call flake int(x),int(y),i*1.5
    next
    wait
[nxt]
    'change t
    t=t+dt
    #gr "discard"
    '#gr "fill black"
wend

#gr "flush"


wait

[quit]
    timer 0
    close #gr
end

[getSlack]
    WindowWidth=200:WindowHeight=200
    open "" for graphics_nsb as #t:#t,"home;posxy x y":close#t
    slackX=WindowWidth-2*x:slackY=WindowHeight-2*y
return

sub flake x0,y0,rr
'#gr "color black"
'#gr "place ";x0;" ";y0;"; circlefilled "; rr+2
'#gr "color white"
'if rr < 5 then call flake2 x0,y0,rr: exit sub
a=0
r=int(rr/3)
' repeat 6 times
    #gr "place ";x0;" ";y0
    #gr "circle ";r+1
for i = 1 to 6
    'draw single "arm" from center
    #gr "place ";x0;" ";y0
    #gr "north; turn ";a
    #gr "up; go ";int(2/3*rr)
    #gr "posxy x y" 'store point
    #gr "turn 60"
    #gr "down; go ";r
    #gr "place ";x;" ";y    'restore point
    #gr "turn -120"
    #gr "go ";r
    #gr "place ";x0;" ";y0
    #gr "north; turn ";a
    #gr "go ";rr

    a=a+60  'each arm turned 60 degrees more
next
end sub

sub flake2 x0,y0,rr
'#gr "color black"
'#gr "place ";x0;" ";y0;"; circlefilled "; rr+2
'#gr "color white"
a=0
' repeat 6 times
for i = 1 to 6
    #gr "place ";x0;" ";y0
    #gr "north; turn ";a
    'draw single "arm" from center
    #gr "go ";rr
    a=a+60  'each arm turned 60 degrees more
next
#gr "set ";x0;" ";y0
end sub
 

Re: Paper Snowflake
Post by tenochtitlanuk on Dec 19th, 2015, 5:58pm

If anyone else chances on this thread, you could find some fantastic snowflake resources via the Evil Mad Scientists website.
http://www.evilmadscientist.com/2008/vector-snowflake-application/
User Image
It would be a good programming exercise to copy/improve some of the ideas in the programs linked from there.

Merry Xmas everyone.

PS Scientists are not usually mad or evil- at least at the start of their careers!

PPS outputting as a vector file means you can run the output into a CNC foam-sheet cutter, router or w.h.y.
Re: Paper Snowflake
Post by tsh73 on Jan 22nd, 2016, 01:08am

today (Dec 21 2016) Kevin & Kell
User Image wink
Re: Paper Snowflake
Post by tenochtitlanuk on Jan 22nd, 2016, 04:08am

Love that, Anatoly!
Have a great New Year- I really enjoy all your contributions. Snowflakes triggered me off in all sorts of directions.
Re: Paper Snowflake
Post by tsh73 on Jan 22nd, 2016, 06:23am

I was fiddling with graphical IDE
It started from reply#7 at BEHOLD !! 1st Graphics IDE.. TURTLE STYLE EDIT and evolved a bit on other basic forum.
Anyway, now it reads this
Code:
north
repeat 6
  home
  go 100
  repeat 6
    go 30
    repeat 6
      go 10
      go -10
      turn 60
    loop
    go -30
    turn 60
  loop
  turn 60
loop
 

and produces that:
User Image
Re: Paper Snowflake
Post by tenochtitlanuk on Jan 23rd, 2016, 11:12am

From my other interest- Raspberry Pi and Python!
User Image