]> gitweb.factorcode.org Git - factor.git/blob - extra/jamshred/tunnel/tunnel.factor
Using literals vocab for defining computed constants
[factor.git] / extra / jamshred / tunnel / tunnel.factor
1 ! Copyright (C) 2007, 2008 Alex Chapman
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays colors combinators kernel literals locals math math.constants math.matrices math.order math.ranges math.vectors math.quadratic random sequences specialized-arrays.float vectors jamshred.oint ;
4 IN: jamshred.tunnel
5
6 CONSTANT: n-segments 5000
7
8 TUPLE: segment < oint number color radius ;
9 C: <segment> segment
10
11 : segment-number++ ( segment -- )
12     [ number>> 1+ ] keep (>>number) ;
13
14 : random-color ( -- color )
15     { 100 100 100 } [ random 100 / >float ] map first3 1.0 <rgba> ;
16
17 CONSTANT: tunnel-segment-distance 0.4
18 CONSTANT: random-rotation-angle $[ pi 20 / ]
19
20 : random-segment ( previous-segment -- segment )
21     clone dup random-rotation-angle random-turn
22     tunnel-segment-distance over go-forward
23     random-color >>color dup segment-number++ ;
24
25 : (random-segments) ( segments n -- segments )
26     dup 0 > [
27         [ dup peek random-segment over push ] dip 1- (random-segments)
28     ] [ drop ] if ;
29
30 CONSTANT: default-segment-radius 1
31
32 : initial-segment ( -- segment )
33     float-array{ 0 0 0 } float-array{ 0 0 -1 } float-array{ 0 1 0 } float-array{ -1 0 0 }
34     0 random-color default-segment-radius <segment> ;
35
36 : random-segments ( n -- segments )
37     initial-segment 1vector swap (random-segments) ;
38
39 : simple-segment ( n -- segment )
40     [ float-array{ 0 0 -1 } n*v float-array{ 0 0 -1 } float-array{ 0 1 0 } float-array{ -1 0 0 } ] keep
41     random-color default-segment-radius <segment> ;
42
43 : simple-segments ( n -- segments )
44     [ simple-segment ] map ;
45
46 : <random-tunnel> ( -- segments )
47     n-segments random-segments ;
48
49 : <straight-tunnel> ( -- segments )
50     n-segments simple-segments ;
51
52 : sub-tunnel ( from to segments -- segments )
53     #! return segments between from and to, after clamping from and to to
54     #! valid values
55     [ sequence-index-range [ clamp-to-range ] curry bi@ ] keep <slice> ;
56
57 : nearer-segment ( segment segment oint -- segment )
58     #! return whichever of the two segments is nearer to the oint
59     [ 2dup ] dip tuck distance [ distance ] dip < -rot ? ;
60
61 : (find-nearest-segment) ( nearest next oint -- nearest ? )
62     #! find the nearest of 'next' and 'nearest' to 'oint', and return
63     #! t if the nearest hasn't changed
64     pick [ nearer-segment dup ] dip = ;
65
66 : find-nearest-segment ( oint segments -- segment )
67     dup first swap rest-slice rot [ (find-nearest-segment) ] curry
68     find 2drop ;
69     
70 : nearest-segment-forward ( segments oint start -- segment )
71     rot dup length swap <slice> find-nearest-segment ;
72
73 : nearest-segment-backward ( segments oint start -- segment )
74     swapd 1+ 0 spin <slice> <reversed> find-nearest-segment ;
75
76 : nearest-segment ( segments oint start-segment -- segment )
77     #! find the segment nearest to 'oint', and return it.
78     #! start looking at segment 'start-segment'
79     number>> over [
80         [ nearest-segment-forward ] 3keep nearest-segment-backward
81     ] dip nearer-segment ;
82
83 : get-segment ( segments n -- segment )
84     over sequence-index-range clamp-to-range swap nth ;
85
86 : next-segment ( segments current-segment -- segment )
87     number>> 1+ get-segment ;
88
89 : previous-segment ( segments current-segment -- segment )
90     number>> 1- get-segment ;
91
92 : heading-segment ( segments current-segment heading -- segment )
93     #! the next segment on the given heading
94     over forward>> v. 0 <=> {
95         { +gt+ [ next-segment ] }
96         { +lt+ [ previous-segment ] }
97         { +eq+ [ nip ] } ! current segment
98     } case ;
99
100 :: distance-to-next-segment ( current next location heading -- distance )
101     [let | cf [ current forward>> ] |
102         cf next location>> v. cf location v. - cf heading v. / ] ;
103
104 :: distance-to-next-segment-area ( current next location heading -- distance )
105     [let | cf [ current forward>> ]
106            h [ next current half-way-between-oints ] |
107         cf h v. cf location v. - cf heading v. / ] ;
108
109 : vector-to-centre ( seg loc -- v )
110     over location>> swap v- swap forward>> proj-perp ;
111
112 : distance-from-centre ( seg loc -- distance )
113     vector-to-centre norm ;
114
115 : wall-normal ( seg oint -- n )
116     location>> vector-to-centre normalize ;
117
118 CONSTANT: distant 1000
119
120 : max-real ( a b -- c )
121     #! sometimes collision-coefficient yields complex roots, so we ignore these (hack)
122     dup real? [
123         over real? [ max ] [ nip ] if
124     ] [
125         drop dup real? [ drop distant ] unless
126     ] if ;
127
128 :: collision-coefficient ( v w r -- c )
129     v norm 0 = [
130         distant
131     ] [
132         [let* | a [ v dup v. ]
133                 b [ v w v. 2 * ]
134                 c [ w dup v. r sq - ] |
135             c b a quadratic max-real ]
136     ] if ;
137
138 : sideways-heading ( oint segment -- v )
139     [ forward>> ] bi@ proj-perp ;
140
141 : sideways-relative-location ( oint segment -- loc )
142     [ [ location>> ] bi@ v- ] keep forward>> proj-perp ;
143
144 : (distance-to-collision) ( oint segment -- distance )
145     [ sideways-heading ] [ sideways-relative-location ]
146     [ nip radius>> ] 2tri collision-coefficient ;
147
148 : collision-vector ( oint segment -- v )
149     dupd (distance-to-collision) swap forward>> n*v ;
150
151 : bounce-forward ( segment oint -- )
152     [ wall-normal ] [ forward>> swap reflect ] [ (>>forward) ] tri ;
153
154 : bounce-left ( segment oint -- )
155     #! must be done after forward
156     [ forward>> vneg ] dip [ left>> swap reflect ]
157     [ forward>> proj-perp normalize ] [ (>>left) ] tri ;
158
159 : bounce-up ( segment oint -- )
160     #! must be done after forward and left!
161     nip [ forward>> ] [ left>> cross ] [ (>>up) ] tri ;
162
163 : bounce-off-wall ( oint segment -- )
164     swap [ bounce-forward ] [ bounce-left ] [ bounce-up ] 2tri ;
165