From bbe9b1551e869800e266053e9cdbe1fed9b33ccb Mon Sep 17 00:00:00 2001 From: Dave Griffiths Date: Mon, 8 Jun 2009 16:26:43 +0100 Subject: [PATCH] added stuff --- hex-ornament/hex-debug.scm | 31 ++ hex-ornament/hex-ornament-before-insects.scm | 392 +++++++++++++++++++ hex-ornament/textures/particle.png | Bin 0 -> 3879 bytes hex-ornament/textures/worm.png | Bin 0 -> 8426 bytes 4 files changed, 423 insertions(+) create mode 100644 hex-ornament/hex-debug.scm create mode 100644 hex-ornament/hex-ornament-before-insects.scm create mode 100644 hex-ornament/textures/particle.png create mode 100644 hex-ornament/textures/worm.png diff --git a/hex-ornament/hex-debug.scm b/hex-ornament/hex-debug.scm new file mode 100644 index 0000000..3497d17 --- /dev/null +++ b/hex-ornament/hex-debug.scm @@ -0,0 +1,31 @@ +(define (direction-normal d) + (let ((a (* 60 0.017453292))) + (vector (sin (* a d)) (cos (* a d)) 0))) + + +(define (build-ngon n) + (let ((p (build-polygons n 'polygon))) + (with-primitive p + (pdata-index-map! + (lambda (i p) + (let ((a (* (/ i n) (* 2 3.141)))) + (vector (cos a) (sin a) 0))) + "p") + (pdata-map! + (lambda (t p) + (let ((p (vtransform p (mmul + (mrotate (vector 0 0 -90)) + (mscale (vector -1 1 1)))))) + (vsub (vmul p 0.45) (vector 0.5 0.5 0)))) + "t" "p") + (pdata-copy "t" "tref") + (pdata-map! (lambda (n) (vector 0 0 1)) "n")) + p)) + +(clear) +(build-ngon 6) +(for ((i (in-range 0 6))) + (with-primitive (build-ribbon 2) + (hint-wire) + (pdata-set "p" 0 (vector 0 0 0)) + (pdata-set "p" 1 (vmul (direction-normal i) 2)))) \ No newline at end of file diff --git a/hex-ornament/hex-ornament-before-insects.scm b/hex-ornament/hex-ornament-before-insects.scm new file mode 100644 index 0000000..b8cb402 --- /dev/null +++ b/hex-ornament/hex-ornament-before-insects.scm @@ -0,0 +1,392 @@ +(require scheme/class) + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +; odds and sods + +; return a version of list l with v inserted at the nth +; position and with c as a counter +(define (insert l n v c) + (cond + ((null? l) l) + ((eq? c n) (cons v (insert (cdr l) n v (+ c 1)))) + (else (cons (car l) (insert (cdr l) n v (+ c 1)))))) + +(define (list-remove l i) + (if (zero? i) + (cdr l) + (cons (car l) (list-remove (cdr l) (- i 1))))) + +(define (shuffle l) + (if (null? l) + '() + (let ((i (random (length l)))) + (cons (list-ref l i) + (shuffle (list-remove l i)))))) + +; convert a list of bools into a number, treating the +; list as a binary sequence +(define (bool-list->num l n c) + (cond + ((null? l) n) + ((car l) (bitwise-ior (arithmetic-shift 1 c) + (bool-list->num (cdr l) n (+ c 1)))) + (else (bool-list->num (cdr l) n (+ c 1))))) + +; how to find your way around a hexagon +; . +; 5 (NW) / \ 0 (NE) +; / \ +; 4 (W)| | 1 (E) +; | | +; \ / +; 3 (SW) \ / 2 (SE) +; ` + +(define NE 0) +(define E 1) +(define SE 2) +(define SW 3) +(define W 4) +(define NW 5) + +(define directions (list NE E SE SW W NW)) + +(define (rdirection d) + (cond + ((eq? d NE) SW) + ((eq? d E) W) + ((eq? d SE) NW) + ((eq? d SW) NE) + ((eq? d W) E) + ((eq? d NW) SE))) + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +; logic + +(define comb-cell% + (class object% + (field + (neighbours '(#f #f #f #f #f #f)) + (contents '()) + (connections '(#f #f #f #f #f #f)) + (visible #f) + (update-me #f)) + + (define/public (update-me?) + (let ((r update-me)) + (set! update-me #f) + r)) + + (define/public (set-visible! s) + (set! update-me #t) + (set! visible s)) + + (define/public (visible?) + visible) + + (define/public (get-neighbours) + neighbours) + + (define/public (get-neighbour d) + (list-ref neighbours d)) + + (define/public (set-neighbour! d n) + (set! neighbours (insert neighbours d n 0))) + + (define/public (get-contents) + contents) + + (define/public (get-connections) + connections) + + (define/public (no-connections?) + (equal? connections (list #f #f #f #f #f #f))) + + (define/public (set-connection! d n) + (set! update-me #t) + (set! visible #t) + (set! connections (insert connections d n 0)) + ; tell all our neighbours to become visible + (for-each + (lambda (n) + (when n (send n set-visible! #t))) + neighbours)) + + (define/public (get-connection d) + (list-ref connections d)) + + (define/public (get-connection-num) + (bool-list->num connections 0 0)) + + ; returns the first attachable neighbour found, and sets it's connection + (define (search/attach-to-neighbour l dirs) + (cond + ((null? l) dirs) + ((not (send (get-neighbour (car l)) no-connections?)) + (send (get-neighbour (car l)) set-connection! (rdirection (car l)) #t) + #;(search/attach-to-neighbour (cdr l) (cons (car l) dirs)) + (car l)) + (else (search/attach-to-neighbour (cdr l) dirs)))) + + (define/public (grow) + ; only possible to grow when we are a clear cell + (when (equal? connections (list #f #f #f #f #f #f)) + (let ((dir (search/attach-to-neighbour (shuffle directions) '()))) + (when dir + (set-connection! dir #t)) + #;(for-each + (lambda (d) + (set-connection! d #t)) + dir)))) + + (super-new))) + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(define honey-comb% + (class object% + (field + (cells '()) + (width 0) + (height 0)) + + (define/public (get-cell x y) + (list-ref cells (+ (* y height) x))) + + (define/public (init w h) + (set! width w) + (set! height h) + + ; first build the cells + (set! cells (build-list (* w h) (lambda (_) (make-object comb-cell%)))) + + ; then stitch them together like this: + + ; o o o o o o o o o o o + ; o o o o o o o o o o o + ; o o o o o o o o o o o + ; o o o o o o o o o o o + + (for ((x (in-range 0 width))) + (for ((y (in-range 0 height))) + (let ((cell (get-cell x y))) + (when (and (< x (- width 1)) (> y 0)) + (send cell set-neighbour! NE (get-cell (if (odd? y) (+ x 1) x) (- y 1)))) + (when (< x (- width 1)) + (send cell set-neighbour! E (get-cell (+ x 1) y))) + (when (and (< x (- width 1)) (< y (- height 1))) + (send cell set-neighbour! SE (get-cell (if (odd? y) (+ x 1) x) (+ y 1)))) + + (when (and (> x 0) (> y 0)) + (send cell set-neighbour! NW (get-cell (if (odd? y) x (- x 1)) (- y 1)))) + (when (> x 0) + (send cell set-neighbour! W (get-cell (- x 1) y))) + (when (and (> x 0) (< y (- height 1))) + (send cell set-neighbour! SW (get-cell (if (odd? y) x (- x 1)) (+ y 1)))))))) + + (define/public (seed x y) + + (send (get-cell x y) set-connection! SE #t) + (send (get-cell x (+ y 1)) set-connection! NW #t) + + #;(let ((seed (get-cell x y))) + ; set all directions to be connected + (for-each + (lambda (d) + (send seed set-connection! d #t)) + directions) + + (for-each + (lambda (n d) + (send n set-connection! (rdirection d) #t)) + (send seed get-neighbours) + directions))) + + (define/public (get-update-list) + (let ((i -1)) + (foldl + (lambda (cell r) + (set! i (+ i 1)) + (if (send cell update-me?) + (cons (list + (list (modulo i width) (quotient i height)) + (send cell get-connection-num)) r) + r)) + '() + cells))) + + (super-new))) + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +; graphics and interaction + +(define (build-ngon n) + (let ((p (build-polygons n 'polygon))) + (with-primitive p + (pdata-index-map! + (lambda (i p) + (let ((a (* (/ i n) (* 2 3.141)))) + (vector (cos a) (sin a) 0))) + "p") + (pdata-map! + (lambda (t p) + (let ((p (vtransform p (mmul + (mrotate (vector 0 0 -90)) + (mscale (vector -1 1 1)))))) + (vsub (vmul p 0.45) (vector 0.5 0.5 0)))) + "t" "p") + (pdata-copy "t" "tref") + (pdata-map! (lambda (n) (vector 0 0 1)) "n")) + p)) + +(define cell-view% + (class object% + (field + (root 0) + (root2 0) + (t 0) + (pos '(0 0)) + (owner 0)) + + (define/public (set-owner! s) + (set! owner s)) + + (define/public (get-root) + root) + + (define/public (get-pos) + pos) + + (define/public (set-pos! s) + (set! pos s)) + + (define (build-prim code) + (let ((p (with-state + ;(hint-wire) + (parent owner) + (hint-depth-sort) + (opacity 0) + (colour (vector 0.9 1 0.5)) + (hint-unlit) + (when (odd? (cadr pos)) + (translate (vector 0.5 0 0))) + (translate (vector (car pos) (* 0.85 (cadr pos)) (* 0.001 (rndf)))) + (scale 0.57) + (rotate (vector 0 0 90)) + (build-ngon 6)))) + (with-primitive p + (update-texture code)) + p)) + + (define/public (build code) + (set! root (build-prim code)) + (set! root2 (build-prim code))) + + (define (update-texture code) + (texture (load-texture "textures/roots-ornate.png")) + (pdata-map! + (lambda (t tref) + (let ((size (/ 1 8))) + (vadd (vmul tref size) (vector (* 1 size (+ 1 (modulo code 8))) + (* size 1 (+ 1 (quotient code 8))) 0)))) + "t" "tref")) + + (define/public (new-code code) + (when (not (zero? root2)) + (destroy root2) + (with-primitive root (opacity 1))) + (set! root2 (build-prim code)) + (set! t 0)) + + (define/public (update) + (set! t (+ t 0.04)) + + (when (< t 1) + (with-primitive root + (opacity (- 1 t))) + (with-primitive root2 + (opacity t))) + + (when (> t 1) + (with-primitive root + (opacity 1)) + + (when (not (zero? root2)) + (destroy root) + (set! root root2) + (set! root2 0)))) + + (super-new))) + + +(define honey-comb-view% + (class object% + (field + (root 0) + (cells '())) ; an associative array mapping position to cell-view obs + + (define/public (init) + (set! root (build-locator))) + + (define (get-pos-from-prim p l) + (cond + ((null? l) #f) + ((eq? (send (cadr (car l)) get-root) p) (caar l)) + (else (get-pos-from-prim p (cdr l))))) + + (define/public (deal-with-input) + (if (mouse-button 1) + (get-pos-from-prim (mouse-over) cells) + #f)) + + (define/public (update update-list) + (for-each + (lambda (cell) + (send (cadr cell) update)) + cells) + (for-each + (lambda (item) + (let* + ((pos (car item)) + (code (cadr item)) + (s (assoc pos cells))) + (cond + (s (send (cadr s) new-code code)) + (else + (let ((cell (make-object cell-view%))) + (send cell set-pos! pos) + (send cell set-owner! root) + (send cell build code) + (set! cells (cons (list pos cell) cells))))))) + update-list)) + + (super-new))) + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(clear) +(clear-colour (vector 0.5 0.2 0.1)) +(clear-texture-cache) +(show-axis 0) +(set-camera-transform (mtranslate (vector 0 0 -8))) + +(define hc (make-object honey-comb%)) +(define hcv (make-object honey-comb-view%)) + +(send hc init 100 100) + +(with-state + (translate (vector -50 -42.5 0)) + (send hcv init)) + +(send hc seed 50 50) +;(send (send hc get-cell 50 52) grow) +;(send (send hc get-cell 49 53) grow) + +(define (animate) + (let ((clicked (send hcv deal-with-input))) + (when clicked + (send (send hc get-cell (car clicked) (cadr clicked)) grow))) + (send hcv update (send hc get-update-list))) + +(every-frame (animate)) diff --git a/hex-ornament/textures/particle.png b/hex-ornament/textures/particle.png new file mode 100644 index 0000000000000000000000000000000000000000..8758f69bc779ffcb730d00f62e0acd3ebca9ca55 GIT binary patch literal 3879 zcmXw62~<SQvKHSrlt+0yci*rY|!Vm;*A;|!! zXnb7|sJNh`0F_eQy>}^%Ven*Ca`FSPSpn&$?Bb?4C+*)Km6!sY4@T`viHfA9#-+s4 zT;08WgN3Tv0H_{wXFCO?z5M55{K+2zby>klxzC4$K55iY!u=D$6Z>2X=%n*5TnS>ebp)>{EWf7MM{eb<3z)y)GsE9QHmEcZB+{^T&p$ zeFia-`MZN&I|dz>W|KdKK6>Ktvi7q>S8Mm&A4{_xvFYjS>-C$I`VcXC_V)5cKWQ4@ zQbx3bXQ41vW;eD|T0dB+zT4?T1Mq=Q<9wi}%8-}xYyD(pz8L-N3Z7vh3w%0jTW31P z5{VK1a48)}dvCviOX$>VU%&nSgS8u}2slh$?$VBY?qaBfp}T?uk@$$w#T} zVEfjSuNcjyZqj|yF5z6;kw;X-!a>X5O{dky^p{j;@{$i=a;4Au8qpW!nRjQqVr$g8)&)w)WNvhW+ShBLX{QO^^o}1g7pGT0b%Lxv(mT2Rim{HGxhz! zpb&{de?qrXJ7gXkQ^>2GI4h49!rw2D&*@XQz1Hd+$VZ4$WvM?}=8UJ+u9f72(}bzj z-|*d2-4n)&)EIIWP6VQBqhy}=*>H){We>bAswX6)F{G@0YrDTM#jEfM;^ajM_ItG~ zt(@)~pu$p-)`2WgZ!D3rT2`O2LG5z*;^ix#)X$+cRbTw~JNxNExSs_!QD;6krHqv2 zNJ*?-td+-mLPzkPnLgydSN7l~+ zAJL>-;U_?DWGqsv^(YuP7PS6B?+vflW!<*{>Ym6+Ti^-&0Ff1GcBiF2fj|q10sC(Q z9IX_(3XGgD5PU(n0gH;50rw#A`;VO8Gh00fX5dj-zKr4tT1Z6!wn$BwRtu>atJXsD z1$5^v7?aM2!eM6+3lJcU~vFMWInS+)%jykfnJm8R|alrng7XxFpQZ{-r z*G5zYyw=1V+76C9f%R*4eTC{!&1mtxc)Z#+T%{t0?IE0v#$DG!vEri*Q{7x*qzUrA zD7}2u)7%TpB;PZ=F$>*k`C=MZ3g6$m2n9xiZ`X{X2o0t=;{kzi?3>U8_YQ+*LnT6h zAu_AY%cJy%fHBK%s&UZ`@KO#=meUyKyl{k9o5>h9Vl^)46E8uE6+w`jqKdIxM+2eq8C*PR?E*-QpKx6Cs}vZkv5JG#`VEZpz;+nnLiE ze8DG({kGP7;^Er}71V|m`Hm#gw^dQlMYjwJR7T4|@mR>qNGQ*3XQqOW>WV33Q>LMY z0%OP%6wgmG8P@>Y0z*aI5~ENC`)9HuGtS22I633G8d?~(r`Uc9Is-Z?O^{xs?0y$L zc^J34F{1h879>s@($v&{VgB<_bsRjZ;&38faS)HSr5(6!KET&OWoY5M!oiAF*TOUA zSee<@Rfj{xwbg5Z1S#PaeQ))L`EGNFy*ruhwWf*W!ES7jNTPrE@v!)tQ#YuHBPcF- zbJYV%IghxtTKoOGm!;^^{B*84j;~AO9B?pGG~zo3?a-icnm2D#G$-c5d0hA_Orw_q z`c=SYLwR|ynmW#k-Ip)7pQPveyZ<-s>-YDk+D1HSu%VU(#I}H_iu$qb;N@S&bWO2y zAgr@aDIQPb?DGm>fE-@+>-K9L@D$|DJ{#Wqb)ZUEd%xCETcHJyVbsc7?7}qt;Xq|R zy^~%2T7J!3F+|$#wC_VTH(Z$NcB4nJ5}=<~3yr9z);Oz;s*mS+6Vmbz?2}&hwZH^v ztzDz%+Hr55D#qQRZ}fdQ&x;JhMAywiwx!_Z=(0xnoG2vS)~XaFtmYf(Z2QW&1+PD5 z7$rfo3ick5zV;o+>tCKauCuf8x^ria)5!Vg_0-Xfv9qI-y6&d;S|{jtg~G zU0oPez?E0TFPqcB%00;l&nS#Bv?rD+ijozMgu*l0oP(AD!1VaG=AL`J>XIz<#7}N~ zLs$p$fyW~hA^xz6IvOTbmu@^^XUd=-Fm4{ANF}HV-*%VnPWF#R!hLp7hX>1uLD)NB z=%cP0ua5>4q32$(jC2Vp$fgKok)?3UCk)#>X2W*9?PcM$i79uxw-4qD)31=Yx}=E; zP%NLv0+=e3X{XrN8y6x}_|4SVJ;Xecqg=^# zWp6Vjc4XSvf{Qf6@UGS!`OVp9xHM9`#tVENX@@-b*5o&Rt~vX0i4UWGq4z4UdiQSd zjZo&B$|9sOiViPImAH0}j`}k+AN(k2h!!HP`0`cKpI>oVGTq<`>0%TI2VGj}N4xosL6 zW6Xs!TI(9Is-c8Ds#o8&C4UXpNQLWz5vC(FZ!EoZtR#7wsk_8XG)|*f;EcAJ>n(@o zU(Cy5@`p2adaZoaKx&YQzR2?-Ndsr;oT)$`1Jr$$wHGW%V52x4cv($x7S*c6&S^{?M7SnEqxQ~i(F9#UtmB@f*j zXNE5_9bA4)du`I0TkSFnT~gttmW(z8UBnJW@ob0AY$!XIlbI@Ctr18PF?TU*%Ac)> z{Cx{&Ly&5%`85L6wWag$agpTGhsvf(V1Y6EP1L>VXrtz#L4{NO7|q6~DYrM>bmGN8 zT)dm+tg3L$N;ab=|D#gCSLpUTRN~a4*2sLBlr#+e?gw@tOTu3n-}6&OmI6FH7UuAY z*E1@Z+AU1|G#v|k5d1eDx+8o64Jc&=5pNawW$Vd4n$#?MQ&3@pGQ>1PwxacqS#Ry9 z=aj2f8@)F!C@$4HHEJ(IL?V>OPRVZU%EjXW_Ly?6-}^!#;Fs{ z-$fE*uzqGai!!QAqBhUOy(8PG;jEHMAp?JWD`8n5ZQ41MWGmBT>Dr{lo9UkR$GX=n zRw4#?^*q?DHDJ3zyFOi6wP`;de!@vzF@bA@<&yA?5gfN_m%5aYe)}QXQ#9!Ib#p*k^RuY}ZF$26tvNa+0gs zX?XMp{jfU7m63BqY3(BF5}%3lO%1|mGcf*HI9jG|1N4-1AG@nLTPA^*(Q`b=u3Xaz zYfziUpNc)oer+in zl#{ae6a3JQvaTasb)LEoAL1cME>Ncyk)0OvKp^W-GKRT0Cd_P9|IV1YZ zHdjA~B3n(EM@86g_Z#Z9TVW@T9$R^?_G;yF2Zm`-0N9WlYytUP;j&UTh|lH~Dy<$p z7hZY$BGof4)o<|j95&3lUlXyb6gzi_@% literal 0 HcmV?d00001 diff --git a/hex-ornament/textures/worm.png b/hex-ornament/textures/worm.png new file mode 100644 index 0000000000000000000000000000000000000000..d7fc55c59ff29a68f973fa68a4d222671a4959b3 GIT binary patch literal 8426 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 J)@WdG{|`eZnQ8z4 literal 0 HcmV?d00001