36
36
< body >
37
37
<!-- <pre></pre> -->
38
38
< canvas > </ canvas >
39
- < script src ="code/bundle.js "> </ script >
39
+ <!-- <script src="code/bundle.js"></script> -->
40
+
41
+ < script >
42
+
43
+ // Find intersection of RAY & SEGMENT
44
+ function getIntersection ( ray , segment ) {
45
+ // RAY in parametric: Point + Delta*T1
46
+ var r_px = ray . a . x ;
47
+ var r_py = ray . a . y ;
48
+ var r_dx = ray . b . x - ray . a . x ;
49
+ var r_dy = ray . b . y - ray . a . y ;
50
+
51
+ // SEGMENT in parametric: Point + Delta*T2
52
+ var s_px = segment . a . x ;
53
+ var s_py = segment . a . y ;
54
+ var s_dx = segment . b . x - segment . a . x ;
55
+ var s_dy = segment . b . y - segment . a . y ;
56
+
57
+ // Are they parallel? If so, no intersect
58
+ var r_mag_squared = r_dx * r_dx + r_dy * r_dy ;
59
+ var s_mag_squared = s_dx * s_dx + s_dy * s_dy ;
60
+ if ( r_dx / r_mag_squared == s_dx / s_mag_squared && r_dy / r_mag_squared == s_dy / s_mag_squared ) {
61
+ // Unit vectors are the same.
62
+ return null ;
63
+ }
64
+
65
+ // SOLVE FOR T1 & T2
66
+ // r_px+r_dx*T1 = s_px+s_dx*T2 && r_py+r_dy*T1 = s_py+s_dy*T2
67
+ // ==> T1 = (s_px+s_dx*T2-r_px)/r_dx = (s_py+s_dy*T2-r_py)/r_dy
68
+ // ==> s_px*r_dy + s_dx*T2*r_dy - r_px*r_dy = s_py*r_dx + s_dy*T2*r_dx - r_py*r_dx
69
+ // ==> T2 = (r_dx*(s_py-r_py) + r_dy*(r_px-s_px))/(s_dx*r_dy - s_dy*r_dx)
70
+ var T2 = ( r_dx * ( s_py - r_py ) + r_dy * ( r_px - s_px ) ) / ( s_dx * r_dy - s_dy * r_dx ) ;
71
+ var T1 = ( s_px + s_dx * T2 - r_px ) / r_dx ;
72
+
73
+ // Must be within parametic whatevers for RAY/SEGMENT
74
+ if ( T1 < 0 ) return null ;
75
+ if ( T2 < 0 || T2 > 1 ) return null ;
76
+
77
+ // Return the POINT OF INTERSECTION
78
+ return {
79
+ x : r_px + r_dx * T1 ,
80
+ y : r_py + r_dy * T1 ,
81
+ param : T1
82
+ } ;
83
+ }
84
+
85
+ function getSightPolygon ( sightX , sightY ) {
86
+ // Get all unique points
87
+ var points = ( function ( segments ) {
88
+ var a = [ ] ;
89
+ segments . forEach ( function ( seg ) {
90
+ a . push ( seg . a , seg . b ) ;
91
+ } ) ;
92
+ return a ;
93
+ } ) ( segments ) ;
94
+
95
+ var uniquePoints = ( function ( points ) {
96
+ var set = { } ;
97
+ return points . filter ( function ( p ) {
98
+ var key = p . x + "," + p . y ;
99
+ if ( key in set ) {
100
+ return false ;
101
+ } else {
102
+ set [ key ] = true ;
103
+ return true ;
104
+ }
105
+ } ) ;
106
+ } ) ( points ) ;
107
+
108
+ // Get all angles
109
+ var uniqueAngles = [ ] ;
110
+ for ( var j = 0 ; j < uniquePoints . length ; j ++ ) {
111
+ var uniquePoint = uniquePoints [ j ] ;
112
+ var angle = Math . atan2 ( uniquePoint . y - sightY , uniquePoint . x - sightX ) ;
113
+ uniquePoint . angle = angle ;
114
+ // uniqueAngles.push(angle - 0.00001, angle, angle + 0.00001);
115
+ uniqueAngles . push ( angle - 0.00001 , angle , angle + 0.00001 ) ;
116
+ }
117
+
118
+ // RAYS IN ALL DIRECTIONS
119
+ var intersects = [ ] ;
120
+ for ( var j = 0 ; j < uniqueAngles . length ; j ++ ) {
121
+ var angle = uniqueAngles [ j ] ;
122
+ // Calculate dx & dy from angle
123
+ var dx = Math . cos ( angle ) ;
124
+ var dy = Math . sin ( angle ) ;
125
+
126
+ // Ray from light coord to point coord
127
+ var ray = {
128
+ a : { x : sightX , y : sightY } ,
129
+ b : { x : sightX + dx , y : sightY + dy }
130
+ } ;
131
+
132
+ // Find CLOSEST intersection
133
+ var closestIntersect = null ;
134
+ for ( var i = 0 ; i < segments . length ; i ++ ) {
135
+ var intersect = getIntersection ( ray , segments [ i ] ) ;
136
+ if ( ! intersect ) continue ;
137
+
138
+ // param (aka distance)
139
+ if ( ! closestIntersect || intersect . param < closestIntersect . param ) {
140
+ closestIntersect = intersect ;
141
+ }
142
+ }
143
+
144
+ // Intersect angle
145
+ if ( ! closestIntersect ) continue ;
146
+ closestIntersect . angle = angle ;
147
+
148
+ // Add to list of intersects
149
+ intersects . push ( closestIntersect ) ;
150
+ }
151
+
152
+ // Sort intersects by angle
153
+ intersects = intersects . sort ( function ( a , b ) {
154
+ return a . angle - b . angle ;
155
+ } ) ;
156
+
157
+ // Polygon is intersects, in order of angle
158
+ return intersects ;
159
+ }
160
+
161
+ ///////////////////////////////////////////////////////
162
+ // DRAWING
163
+ var canvas = document . querySelector ( "canvas" ) ;
164
+ canvas . width = window . innerWidth ;
165
+ canvas . height = window . innerHeight ;
166
+
167
+ var ctx = canvas . getContext ( "2d" ) ;
168
+
169
+ function draw ( ) {
170
+ // Clear canvas
171
+ ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ) ;
172
+
173
+ ctx . fillStyle = '#000' ;
174
+ ctx . fillRect ( 0 , 0 , canvas . width , canvas . height ) ;
175
+
176
+ // Draw segments
177
+ ctx . strokeStyle = "#999" ;
178
+ for ( var i = 0 ; i < segments . length ; i ++ ) {
179
+ var seg = segments [ i ] ;
180
+ ctx . beginPath ( ) ;
181
+ ctx . moveTo ( seg . a . x , seg . a . y ) ;
182
+ ctx . lineTo ( seg . b . x , seg . b . y ) ;
183
+ ctx . stroke ( ) ;
184
+ }
185
+
186
+ var lightsCount = 1 ;
187
+
188
+
189
+ performance . mark ( 'getSightPolygonStart' ) ;
190
+
191
+ // Sight Polygons
192
+ var fuzzyRadius = 0 ;
193
+ var polygons = [ getSightPolygon ( Mouse . x , Mouse . y ) ] ;
194
+ for ( var angle = 0 ; angle < Math . PI * 2 ; angle += ( Math . PI * 2 ) / lightsCount ) {
195
+ var dx = Math . cos ( angle ) * fuzzyRadius ;
196
+ var dy = Math . sin ( angle ) * fuzzyRadius ;
197
+ polygons . push ( getSightPolygon ( Mouse . x + dx , Mouse . y + dy ) ) ;
198
+ } ;
199
+
200
+ performance . mark ( 'getSightPolygonEnd' ) ;
201
+ performance . measure ( 'getSightPolygon' , 'getSightPolygonStart' , 'getSightPolygonEnd' ) ;
202
+
203
+
204
+ // DRAW AS A GIANT POLYGON
205
+ for ( var i = 1 ; i < polygons . length ; i ++ ) {
206
+ drawPolygon ( polygons [ i ] , ctx , `rgba(255, 255, 255, ${ 1 / lightsCount } )` ) ;
207
+ }
208
+ drawPolygon ( polygons [ 0 ] , ctx , "#fff" ) ;
209
+
210
+
211
+ // Draw red dots
212
+ ctx . fillStyle = "#dd3838" ;
213
+ ctx . beginPath ( ) ;
214
+ ctx . arc ( Mouse . x , Mouse . y , 2 , 0 , 2 * Math . PI , false ) ;
215
+ ctx . fill ( ) ;
216
+ for ( var angle = 0 ; angle < Math . PI * 2 ; angle += ( Math . PI * 2 ) / lightsCount ) {
217
+ var dx = Math . cos ( angle ) * fuzzyRadius ;
218
+ var dy = Math . sin ( angle ) * fuzzyRadius ;
219
+ ctx . beginPath ( ) ;
220
+ ctx . arc ( Mouse . x + dx , Mouse . y + dy , 2 , 0 , 2 * Math . PI , false ) ;
221
+ ctx . fill ( ) ;
222
+ }
223
+ }
224
+
225
+ function drawPolygon ( polygon , ctx , fillStyle ) {
226
+ ctx . fillStyle = 'rgba(255, 255, 255, 0.1)' ; //fillStyle;
227
+ ctx . strokeStyle = '#3f0' ;
228
+ ctx . beginPath ( ) ;
229
+ ctx . moveTo ( polygon [ 0 ] . x , polygon [ 0 ] . y ) ;
230
+ for ( var i = 1 ; i < polygon . length ; i ++ ) {
231
+ var intersect = polygon [ i ] ;
232
+ ctx . lineTo ( intersect . x , intersect . y ) ;
233
+ }
234
+ ctx . fill ( ) ;
235
+ ctx . stroke ( ) ;
236
+
237
+
238
+ ctx . beginPath ( ) ;
239
+ ctx . moveTo ( Mouse . x , Mouse . y ) ;
240
+ ctx . moveTo ( polygon [ 0 ] . x , polygon [ 0 ] . y ) ;
241
+ for ( var i = 1 ; i < polygon . length ; i ++ ) {
242
+ var intersect = polygon [ i ] ;
243
+ ctx . moveTo ( Mouse . x , Mouse . y ) ;
244
+ ctx . lineTo ( intersect . x , intersect . y ) ;
245
+ }
246
+ ctx . stroke ( ) ;
247
+
248
+
249
+ ctx . fillStyle = 'rgba(255, 255, 255, 1)' ; //fillStyle;
250
+
251
+ for ( var i = 1 ; i < polygon . length ; i ++ ) {
252
+ var intersect = polygon [ i ] ;
253
+ ctx . fillText ( i , intersect . x , intersect . y ) ;
254
+ }
255
+ // ctx.fill();
256
+ }
257
+
258
+ const kx = window . innerWidth / 640 ;
259
+ const ky = window . innerHeight / 360 ;
260
+
261
+ // LINE SEGMENTS
262
+ var segments = [
263
+ // Border
264
+ { a : { x : kx * 5 , y : ky * 5 } , b : { x : kx * 630 , y : ky * 5 } } ,
265
+ { a : { x : kx * 630 , y : ky * 5 } , b : { x : kx * 630 , y : ky * 350 } } ,
266
+ { a : { x : kx * 630 , y : ky * 350 } , b : { x : kx * 5 , y : ky * 350 } } ,
267
+ { a : { x : kx * 5 , y : ky * 350 } , b : { x : kx * 5 , y : ky * 5 } } ,
268
+ // Polygon #1
269
+ { a : { x : kx * 100 , y : ky * 150 } , b : { x : kx * 120 , y : ky * 50 } } ,
270
+ { a : { x : kx * 120 , y : ky * 50 } , b : { x : kx * 200 , y : ky * 80 } } ,
271
+ { a : { x : kx * 200 , y : ky * 80 } , b : { x : kx * 140 , y : ky * 210 } } ,
272
+ { a : { x : kx * 140 , y : ky * 210 } , b : { x : kx * 100 , y : ky * 150 } } ,
273
+ // Polygon #2
274
+ { a : { x : kx * 100 , y : ky * 200 } , b : { x : kx * 120 , y : ky * 250 } } ,
275
+ { a : { x : kx * 120 , y : ky * 250 } , b : { x : kx * 60 , y : ky * 300 } } ,
276
+ { a : { x : kx * 60 , y : ky * 300 } , b : { x : kx * 100 , y : ky * 200 } } ,
277
+ // Polygon #3
278
+ { a : { x : kx * 200 , y : ky * 260 } , b : { x : kx * 220 , y : ky * 150 } } ,
279
+ { a : { x : kx * 220 , y : ky * 150 } , b : { x : kx * 300 , y : ky * 200 } } ,
280
+ { a : { x : kx * 300 , y : ky * 200 } , b : { x : kx * 350 , y : ky * 320 } } ,
281
+ { a : { x : kx * 350 , y : ky * 320 } , b : { x : kx * 200 , y : ky * 260 } } ,
282
+ // Polygon #4
283
+ { a : { x : kx * 340 , y : ky * 60 } , b : { x : kx * 360 , y : ky * 40 } } ,
284
+ { a : { x : kx * 360 , y : ky * 40 } , b : { x : kx * 370 , y : ky * 70 } } ,
285
+ { a : { x : kx * 370 , y : ky * 70 } , b : { x : kx * 340 , y : ky * 60 } } ,
286
+ // Polygon #5
287
+ { a : { x : kx * 450 , y : ky * 190 } , b : { x : kx * 560 , y : ky * 170 } } ,
288
+ { a : { x : kx * 560 , y : ky * 170 } , b : { x : kx * 540 , y : ky * 270 } } ,
289
+ { a : { x : kx * 540 , y : ky * 270 } , b : { x : kx * 430 , y : ky * 290 } } ,
290
+ { a : { x : kx * 430 , y : ky * 290 } , b : { x : kx * 450 , y : ky * 190 } } ,
291
+ // Polygon #6
292
+ { a : { x : kx * 400 , y : ky * 95 } , b : { x : kx * 580 , y : ky * 50 } } ,
293
+ { a : { x : kx * 580 , y : ky * 50 } , b : { x : kx * 480 , y : ky * 150 } } ,
294
+ { a : { x : kx * 480 , y : ky * 150 } , b : { x : kx * 400 , y : ky * 95 } }
295
+ ] ;
296
+ // DRAW LOOP
297
+
298
+ var updateCanvas = true ;
299
+
300
+ function drawLoop ( ) {
301
+ requestAnimationFrame ( drawLoop ) ;
302
+ if ( updateCanvas ) {
303
+ draw ( ) ;
304
+ updateCanvas = false ;
305
+ }
306
+ }
307
+ window . onload = function ( ) {
308
+ drawLoop ( ) ;
309
+ } ;
310
+ // MOUSE
311
+ var Mouse = {
312
+ x : canvas . width / 2 ,
313
+ y : canvas . height / 2
314
+ } ;
315
+ canvas . onmousemove = function ( event ) {
316
+ Mouse . x = event . clientX ;
317
+ Mouse . y = event . clientY ;
318
+ updateCanvas = true ;
319
+ } ;
320
+
321
+ </ script >
40
322
</ body >
41
323
42
324
</ html >
0 commit comments