11<!doctype html>
22< html class ="no-js " lang ="en ">
33< head >
4- < meta charset ="utf-8 ">
5- < style >
6- body {font-family : Helvetica, sans-serif;}
7- table {background-color : # CCDDEE ;text-align : left}
8- </ style >
4+ < meta charset ="utf-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1 ">
6+ < link rel ="stylesheet " href ="https://interactivecomputergraphics.github.io/physics-simulation/examples/style.css ">
97 < script type ="text/x-mathjax-config ">
108 MathJax . Hub . Config ( {
119 extensions : [ "tex2jax.js" ] ,
1816 "HTML-CSS" : { fonts : [ "TeX" ] }
1917 } ) ;
2018 </ script >
21- < script type ="text/javascript " aync src ="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js "> </ script >
19+ < script type ="text/javascript " async src ="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js "> </ script >
2220 < title > Neighborhood Search</ title >
2321</ head >
2422< body >
23+
24+ < header class ="page-header ">
25+ < h1 > Neighborhood Search</ h1 >
26+ </ header >
27+
2528< main >
26- < h1 style =" text-align:center " > Neighborhood Search </ h1 >
29+ <!-- Simulation panel: canvas + controls -- >
2730 < table style ="align_center;border-radius: 20px;padding: 20px;margin:auto ">
28- < col width ="1100 ">
29- < col width ="400 ">
31+ < col width ="1200 ">
32+ < col width ="300 ">
3033 < tr >
3134 < td >
32- < canvas id ="simCanvas " width ="1024 " height ="768 " style ="border:2px solid #000000;border-radius: 20px;background-color:#EEEEEE "> Your browser does not support the HTML5 canvas tag.</ canvas >
35+ < div class ="card sim-panel ">
36+ < div class ="sim-canvas-wrap ">
37+ < canvas id ="simCanvas " width ="1024 " height ="768 " style ="border:2px solid #000000;border-radius: 20px;background-color:#EEEEEE "> Your browser does not support the HTML5 canvas tag.</ canvas >
38+ </ div >
39+ </ div >
3340 </ td >
3441 < td >
35- < table >
36- < col width ="180 " style ="padding-right:10px ">
37- < col width ="100 ">
38- < tr >
39- < td > < label > Time per step</ label > </ td >
40- < td > < span id ="timePerStep "> 0.00</ span > ms</ td >
41- </ tr >
42- < tr >
43- < td > < label > # particles</ label > </ td >
44- < td > < span id ="numParticles "> 0</ span > </ td >
45- </ tr >
46- < tr >
47- < td > < label for ="widthInput "> Width</ label > </ td >
48- < td > < input onchange ="gui.restart() " id ="widthInput " type ="number " value ="30 " step ="1 "> </ td >
49- </ tr >
50- < tr >
51- < td > < label for ="heightInput "> Height</ label > </ td >
52- < td > < input onchange ="gui.restart() " id ="heightInput " type ="number " value ="30 " step ="1 "> </ td >
53- </ tr >
54- < tr >
55- < td > < label > Particle radius</ label > </ td >
56- < td > < span > 0.025</ span > </ td >
57- </ tr >
58- < tr >
59- < td > < label for ="supportRadiusInput "> Support radius</ label > </ td >
60- < td > < input onchange ="gui.restart() " id ="supportRadiusInput " value ="0.1 " type ="input "> </ td >
61- </ tr >
62- < tr >
63- < td > </ td >
64- < td > < button onclick ="gui.restart() " type ="button " id ="restart "> Restart</ button > </ td >
65- </ tr >
66- < tr >
67- < td > </ td >
68- < td > < button onclick ="gui.doPause() " type ="button " id ="Pause "> Pause</ button > </ td >
69- </ tr >
70- </ table >
42+ < div class ="controls-panel ">
43+ < h3 > Controls</ h3 >
44+ < div class ="controls-grid ">
45+ < label > Time per step</ label >
46+ < span class ="stat-value "> < span id ="timePerStep "> 0.00</ span > ms</ span >
47+
48+ < label > # particles</ label >
49+ < span class ="stat-value "> < span id ="numParticles "> 0</ span > </ span >
50+
51+ < label for ="widthInput "> Width</ label >
52+ < input onchange ="gui.restart() " id ="widthInput " type ="number " value ="30 " step ="1 ">
53+
54+ < label for ="heightInput "> Height</ label >
55+ < input onchange ="gui.restart() " id ="heightInput " type ="number " value ="30 " step ="1 ">
56+
57+ < label > Particle radius</ label >
58+ < span class ="stat-value "> < span > 0.025</ span > m</ span >
59+
60+ < label for ="supportRadiusInput "> Support radius</ label >
61+ < input onchange ="gui.restart() " id ="supportRadiusInput " value ="0.1 " type ="input ">
62+
63+ < div class ="full-width ">
64+ < button onclick ="gui.restart() " id ="restart "> ▶ Restart</ button >
65+ </ div >
66+ < div class ="full-width ">
67+ < button onclick ="gui.doPause() " id ="Pause " class ="btn-secondary "> ▮▮ Pause</ button >
68+ </ div >
69+ </ div >
70+ </ div >
7171 </ td >
7272 </ tr >
73- < tr > < td >
73+ </ table >
74+
75+ <!-- Theory section -->
76+ < div class ="card theory ">
7477 < h2 > Neighborhood search using spatial hashing:</ h2 >
7578 < p > This example shows how the neighborhood of a particle is determined using spatial hashing [THM+03]. For each particle we want to find its neighbors within a given radius (the support radius of the kernel function). </ p >
7679
@@ -83,8 +86,7 @@ <h3>References</h3>
8386 < ul >
8487 < li > [THM+03] Matthias Teschner, Bruno Heidelberger, Matthias Müller, Danat Pomeranets, Markus Gross. Optimized Spatial Hashing for Collision Detection of Deformable Objects. In Proceedings of VMV, 2003.</ li >
8588 </ ul >
86- </ td > </ tr >
87- </ table >
89+ </ div >
8890
8991</ main >
9092
@@ -326,7 +328,7 @@ <h3>References</h3>
326328 {
327329 let p = this . sim . particles [ i ] ;
328330 let r = this . sim . particleRadius ;
329- this . c . fillStyle = 'hsl(225 ,100%,40%)' ;
331+ this . c . fillStyle = 'hsl(205 ,100%,40%)' ;
330332 let px = this . origin . x + p . x * this . zoom ;
331333 let py = this . origin . y - p . y * this . zoom ;
332334
@@ -357,29 +359,21 @@ <h3>References</h3>
357359 // draw selected particle in red
358360 let p = this . sim . particles [ this . selectedParticle ] ;
359361 let r = this . sim . particleRadius ;
360- this . c . fillStyle = "#DD0000 " ;
362+ this . c . fillStyle = "#CC0000 " ;
361363 let px = this . origin . x + p . x * this . zoom ;
362364 let py = this . origin . y - p . y * this . zoom ;
363365 this . c . beginPath ( ) ;
364366 this . c . arc ( px , py , r * this . zoom , 0 , Math . PI * 2 , true ) ;
365367 this . c . closePath ( ) ;
366368 this . c . fill ( ) ;
367-
368- // draw a red circle to show the support radius
369- this . c . strokeStyle = "#FF0000" ;
370- this . c . lineWidth = 2 ;
371- this . c . beginPath ( ) ;
372- this . c . arc ( px , py , this . sim . supportRadius * this . zoom , 0 , Math . PI * 2 , false ) ;
373- this . c . closePath ( ) ;
374- this . c . stroke ( ) ;
375-
369+
376370 // draw neighbors in green
377371 for ( let j = 0 ; j < p . neighbors . length ; j ++ )
378372 {
379373 let nj = p . neighbors [ j ] ;
380374 let p_j = this . sim . particles [ nj ] ;
381375 let r = this . sim . particleRadius ;
382- this . c . fillStyle = 'hsl(130 ,100%,30%)' ;
376+ this . c . fillStyle = 'hsl(150 ,100%,30%)' ;
383377 let px = this . origin . x + p_j . x * this . zoom ;
384378 let py = this . origin . y - p_j . y * this . zoom ;
385379
@@ -388,6 +382,16 @@ <h3>References</h3>
388382 this . c . closePath ( ) ;
389383 this . c . fill ( ) ;
390384 }
385+
386+ // draw a red circle to show the support radius
387+ this . c . strokeStyle = "#FF0000" ;
388+ this . c . lineWidth = 2 ;
389+ this . c . beginPath ( ) ;
390+ this . c . arc ( px , py , this . sim . supportRadius * this . zoom , 0 , Math . PI * 2 , false ) ;
391+ this . c . closePath ( ) ;
392+ this . c . stroke ( ) ;
393+
394+
391395 }
392396
393397
@@ -448,10 +452,12 @@ <h3>References</h3>
448452
449453 getMousePos ( canvas , event )
450454 {
451- let rect = canvas . getBoundingClientRect ( ) ;
455+ const rect = canvas . getBoundingClientRect ( ) ;
456+ const scaleX = canvas . width / rect . width ; // buffer / displayed size
457+ const scaleY = canvas . height / rect . height ;
452458 return {
453- x : event . clientX - rect . left ,
454- y : event . clientY - rect . top
459+ x : ( event . clientX - rect . left ) * scaleX ,
460+ y : ( event . clientY - rect . top ) * scaleY
455461 } ;
456462 }
457463
0 commit comments