USING: arrays kernel math sequences locals math.order math.vectors accessors opengl opengl.gl ui ui.gadgets ui.gadgets.canvas ui.render ; IN: dragon ! : zig ( p1 p2 -- p1 pI p2 ) ! [ [ first2 ] bi@ ! [ [ rot swap + swap ] dip - + 2 / ] 4keep ! [ rot + swap ] dip + + 2 / 2array ! ] 2keep [ swap ] dip ; ! : zag ( p1 p2 -- p1 pA p2 ) ! [ [ first2 ] bi@ ! [ [ rot swap + swap ] dip + - 2 / ] 4keep ! [ rot swap - swap ] dip + + 2 / 2array ! ] 2keep [ swap ] dip ; :: zig ( p1 p2 -- p1 pI p2 ) p1 first2 :> ( x1 y1 ) p2 first2 :> ( x2 y2 ) p1 x1 x2 + y1 y2 - + 2 / x2 x1 - y1 y2 + + 2 / 2array p2 ; :: zag ( p1 p2 -- p1 pA p2 ) p1 first2 :> ( x1 y1 ) p2 first2 :> ( x2 y2 ) p1 x1 x2 + y1 y2 + - 2 / x1 x2 - y1 y2 + + 2 / 2array p2 ; ! : dragon' ( p1 p2 p3 d -- seq ) ! dup zero? [ ! 2drop 2array ! ] [ ! 1 - swap dupd swap [ dupd swap ] 2dip ! p1 p2 d p2 p3 d ! [ zig ] 4dip [ zag ] dip ! p1 pI p2 d p2 pA p3 d ! [ dragon' ] 4dip dragon' ! p1 pI p2 d dragon' / p2 pA p3 d dragon' ! append ! ] if; :: dragon' ( p1 p2 p3 d -- seq ) d zero? [ p1 p2 2array ] [ p1 p2 zig d 1 - dragon' p2 p3 zag d 1 - dragon' append ] if ; : dragon ( -- seq ) { 100 100 } { 356 100 } zig 15 dragon' ; ! --- : draw-dragon ( n -- ) 1 glLineWidth 1 glPointSize 1.0 1.0 1.0 1.0 glColor4d drop GL_LINE_STRIP glBegin dragon [ first2 glVertex2d ] each glEnd ; TUPLE: dragon-canvas < canvas ; M: dragon-canvas layout* delete-canvas-dlist ; M: dragon-canvas draw-gadget* [ dim>> first2 min 3 /i draw-dragon ] draw-canvas ; M: dragon-canvas pref-dim* drop { 430 300 } ; MAIN-WINDOW: dragon-window { { title "Dragon Curve" } } dragon-canvas new-canvas >>gadgets ; MAIN: dragon-window