Skip to content

Commit 4932e3b

Browse files
committed
- new style
1 parent 36053bd commit 4932e3b

4 files changed

Lines changed: 288 additions & 289 deletions

File tree

examples/ibds.html

Lines changed: 75 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
<html class="no-js" lang="en">
33
<head>
44
<meta charset="utf-8">
5-
<style>
6-
body {font-family: Helvetica, sans-serif;}
7-
table {background-color:#CCDDEE;text-align:left}
8-
</style>
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"],
@@ -18,83 +16,82 @@
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>Impulse-Based Dynamic Simulation</title>
2321
</head>
2422
<body>
23+
24+
<header class="page-header">
25+
<h1>Impulse-Based Dynamic Simulation</h1>
26+
</header>
27+
2528
<main>
26-
<h1 style="text-align:center">Impulse-Based Dynamic Simulation</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="75%">
32+
<col width="25%">
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="960" 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>Current time</label></td>
40-
<td><span id="time">0.00</span> s</td>
41-
</tr>
42-
<tr>
43-
<td><label>Time per sim. step</label></td>
44-
<td><span id="timePerStep">0.00</span> ms</td>
45-
</tr>
46-
<tr>
47-
<td><label># particles</label></td>
48-
<td><span id="numParticles">0</span></td>
49-
</tr>
50-
<tr>
51-
<td><label># constraints</label></td>
52-
<td><span id="numConstraints">0</span></td>
53-
</tr>
54-
<tr>
55-
<td><label for="widthInput">Width</label></td>
56-
<td><input onchange="gui.restart()" id="widthInput" type="number" value="40" step="1"></td>
57-
</tr>
58-
<tr>
59-
<td><label for="heightInput">Height</label></td>
60-
<td><input onchange="gui.restart()" id="heightInput" type="number" value="30" step="1"></td>
61-
</tr>
62-
<tr>
63-
<td><label for="fixedParticlesInput"># fixed particles</label></td>
64-
<td><select onchange="gui.restart()" id="fixedParticlesInput">
65-
<option value="1">1</option>
66-
<option value="2" selected="selected">2</option>
67-
<option value="4">4</option>
68-
</select></td>
69-
</tr>
70-
<tr>
71-
<td><label for="timeStepSizeInput">Time step size</label></td>
72-
<td><input onchange="gui.sim.timeStepSize=parseFloat(value)" id="timeStepSizeInput" type="number" value="0.005" step="0.001"></td>
73-
</tr>
74-
<tr>
75-
<td><label for="iterationsInput">Iterations</label></td>
76-
<td><input onchange="gui.sim.numIterations=parseInt(value)" id="iterationsInput" type="number" value="2" step="1"></td>
77-
</tr>
78-
<tr>
79-
<td><label for="gravityInput">Gravity</label></td>
80-
<td><input onchange="gui.sim.gravity=parseFloat(value)" id="gravityInput" type="number" value="-9.81" step="0.01"></td>
81-
</tr>
82-
<tr>
83-
<td><label for="massInput">Mass</label></td>
84-
<td><input onchange="gui.sim.mass=parseFloat(value)" id="massInput" type="number" value="0.5" step="0.01"></td>
85-
</tr>
86-
<tr>
87-
<td></td>
88-
<td><button onclick="gui.restart()" type="button" id="restart">Restart</button></td>
89-
</tr>
90-
<tr>
91-
<td></td>
92-
<td><button onclick="gui.doPause()" type="button" id="Pause">Pause</button></td>
93-
</tr>
94-
</table>
42+
<div class="controls-panel">
43+
<h3>Controls</h3>
44+
<div class="controls-grid">
45+
<label>Current time</label>
46+
<span class="stat-value"><span id="time">0.00</span> s</span>
47+
48+
<label>Time per sim. step</label>
49+
<span class="stat-value"><span id="timePerStep">0.00</span> ms</span>
50+
51+
<label># particles</label>
52+
<span class="stat-value"><span id="numParticles">0</span></span>
53+
54+
<label># constraints</label>
55+
<span class="stat-value"><span id="numConstraints">0</span></span>
56+
57+
<label for="widthInput">Width</label>
58+
<input onchange="gui.restart()" id="widthInput" type="number" value="40" step="1">
59+
60+
<label for="heightInput">Height</label>
61+
<input onchange="gui.restart()" id="heightInput" type="number" value="30" step="1">
62+
63+
<label for="fixedParticlesInput"># fixed particles</label>
64+
<select onchange="gui.restart()" id="fixedParticlesInput">
65+
<option value="1">1</option>
66+
<option value="2" selected="selected">2</option>
67+
<option value="4">4</option>
68+
</select>
69+
70+
<label for="timeStepSizeInput">Time step size</label>
71+
<input onchange="gui.sim.timeStepSize=parseFloat(value)" id="timeStepSizeInput" type="number" value="0.005" step="0.001">
72+
73+
<label for="iterationsInput">Iterations</label>
74+
<input onchange="gui.sim.numIterations=parseInt(value)" id="iterationsInput" type="number" value="2" step="1">
75+
76+
<label for="gravityInput">Gravity</label>
77+
<input onchange="gui.sim.gravity=parseFloat(value)" id="gravityInput" type="number" value="-9.81" step="0.01">
78+
79+
<label for="massInput">Mass</label>
80+
<input onchange="gui.sim.mass=parseFloat(value)" id="massInput" type="number" value="0.5" step="0.01">
81+
<div class="full-width">
82+
<button onclick="gui.restart()" id="restart">&#9654; Restart</button>
83+
</div>
84+
<div class="full-width">
85+
<button onclick="gui.doPause()" id="Pause" class="btn-secondary">&#9646;&#9646; Pause</button>
86+
</div>
87+
</div>
88+
</div>
9589
</td>
9690
</tr>
97-
<tr><td>
91+
</table>
92+
93+
<!-- Theory section -->
94+
<div class="card theory">
9895
<h2>IBDS algorithm:</h2>
9996
This example shows the impulse-based dynamic simulation (IBDS) method [BFS05, BS06].
10097
IBDS is a predictor-corrector method to perform a simulation step for a constrained system.
@@ -165,13 +162,13 @@ <h3>5. Velocity update:</h3>
165162
Finally, the velocity of a constrained particle is updated:
166163
$$\Delta \mathbf v = \frac{1}{m} \mathbf p$$
167164

168-
<h3>Velocity constraint solver loop</h3>
165+
<h3>6. Velocity constraint solver loop</h3>
169166
The velocity constraints $\dot C(\mathbf x) = 0$ are solved analogously to the position constraints.
170167
The Lagrange multipliers are determined by solving:
171168
$$\mathbf J \mathbf M^{-1} \mathbf J^T \boldsymbol \lambda = -\mathbf {\dot C}(\mathbf x).$$
172169
However, note that no position prediction is required since the solve is performed after the time integration step.
173170

174-
<h3>Time integration</h3>
171+
<h3>7. Time integration</h3>
175172
The particles are advected by numerical time integration. In our case we use a symplectic Euler method:
176173
$$\begin{align*}
177174
\mathbf v(t + \Delta t) &= \mathbf v(t) + \frac{\Delta t}{m} \mathbf f^{\text{ext}}(t) \\
@@ -185,8 +182,7 @@ <h3>References</h3>
185182
<li>[BFS05] Jan Bender, Dieter Finkenzeller and Alfred Schmitt. An impulse-based dynamic simulation system for VR applications. In Proceedings of Virtual Concept 2005 </li>
186183
</ul>
187184

188-
</td></tr>
189-
</table>
185+
</div>
190186

191187
</main>
192188

@@ -618,10 +614,12 @@ <h3>References</h3>
618614

619615
getMousePos(canvas, event)
620616
{
621-
let rect = canvas.getBoundingClientRect();
617+
const rect = canvas.getBoundingClientRect();
618+
const scaleX = canvas.width / rect.width; // buffer / displayed size
619+
const scaleY = canvas.height / rect.height;
622620
return {
623-
x: event.clientX - rect.left,
624-
y: event.clientY - rect.top
621+
x: (event.clientX - rect.left) * scaleX,
622+
y: (event.clientY - rect.top) * scaleY
625623
};
626624
}
627625

examples/iisph.html

Lines changed: 72 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
<html class="no-js" lang="en">
33
<head>
44
<meta charset="utf-8">
5-
<style>
6-
body {font-family: Helvetica, sans-serif;}
7-
table {background-color:#CCDDEE;text-align:left}
8-
</style>
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"],
@@ -18,79 +16,79 @@
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>Implicit Incompressible SPH (IISPH)</title>
2321
</head>
2422
<body>
23+
24+
<header class="page-header">
25+
<h1>Implicit Incompressible SPH (IISPH)</h1>
26+
</header>
27+
2528
<main>
26-
<h1 style="text-align:center">Implicit Incompressible SPH (IISPH)</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="75%">
32+
<col width="25%">
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="960" 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>Current time</label></td>
40-
<td><span id="time">0.00</span> s</td>
41-
</tr>
42-
<tr>
43-
<td><label>Time per sim. step</label></td>
44-
<td><span id="timePerStep">0.00</span> ms</td>
45-
</tr>
46-
<tr>
47-
<td><label>Required iterations</label></td>
48-
<td><span id="iterations">0</span></td>
49-
</tr>
50-
<tr>
51-
<td><label># particles</label></td>
52-
<td><span id="numParticles">0</span></td>
53-
</tr>
54-
<tr>
55-
<td><label for="widthInput">Width</label></td>
56-
<td><input onchange="gui.restart()" id="widthInput" type="number" value="30" step="1"></td>
57-
</tr>
58-
<tr>
59-
<td><label for="heightInput">Height</label></td>
60-
<td><input onchange="gui.restart()" id="heightInput" type="number" value="30" step="1"></td>
61-
</tr>
62-
<tr>
63-
<td><label for="timeStepSizeInput">Time step size</label></td>
64-
<td><input onchange="gui.sim.timeStepSize=parseFloat(value)" id="timeStepSizeInput" type="number" value="0.005" step="0.001"></td>
65-
</tr>
66-
<tr>
67-
<td><label for="maxErrorInput">Max. density error (%)</label></td>
68-
<td><input onchange="gui.sim.maxError=parseFloat(value)" id="maxErrorInput" type="number" value="0.1" step="0.01"></td>
69-
</tr>
70-
<tr>
71-
<td><label for="iterationsInput">Max. iterations</label></td>
72-
<td><input onchange="gui.sim.maxIterations=parseInt(value)" id="iterationsInput" type="number" value="100" step="1"></td>
73-
</tr>
74-
<tr>
75-
<td><label for="viscosityInput">Viscosity</label></td>
76-
<td><input onchange="gui.sim.viscosity=parseFloat(value)" id="viscosityInput" type="number" value="0.05" step="0.01"></td>
77-
</tr>
78-
<tr>
79-
<td><label for="gravityInput">Gravity</label></td>
80-
<td><input onchange="gui.sim.gravity=parseFloat(value)" id="gravityInput" type="number" value="-9.81" step="0.01"></td>
81-
</tr>
82-
<tr>
83-
<td></td>
84-
<td><button onclick="gui.restart()" type="button" id="restart">Restart</button></td>
85-
</tr>
86-
<tr>
87-
<td></td>
88-
<td><button onclick="gui.doPause()" type="button" id="Pause">Pause</button></td>
89-
</tr>
90-
</table>
42+
<div class="controls-panel">
43+
<h3>Controls</h3>
44+
<div class="controls-grid">
45+
<label>Current time</label>
46+
<span class="stat-value"><span id="time">0.00</span> s</span>
47+
48+
<label>Time per sim. step</label>
49+
<span class="stat-value"><span id="timePerStep">0.00</span> ms</span>
50+
51+
<label>Required iterations</label>
52+
<span id="iterations">0</span>
53+
54+
<label># particles</label>
55+
<span class="stat-value"><span id="numParticles">0</span></span>
56+
57+
<label for="widthInput">Width</label>
58+
<input onchange="gui.restart()" id="widthInput" type="number" value="40" step="1">
59+
60+
<label for="heightInput">Height</label>
61+
<input onchange="gui.restart()" id="heightInput" type="number" value="30" step="1">
62+
63+
<label for="timeStepSizeInput">Time step size</label>
64+
<input onchange="gui.sim.timeStepSize=parseFloat(value)" id="timeStepSizeInput" type="number" value="0.002" step="0.001">
65+
66+
<label for="maxErrorInput">Max. density error (%)</label>
67+
<input onchange="gui.sim.maxError=parseFloat(value)" id="maxErrorInput" type="number" value="0.1" step="0.01">
68+
69+
<label for="iterationsInput">Max. iterations</label>
70+
<input onchange="gui.sim.maxIterations=parseInt(value)" id="iterationsInput" type="number" value="100" step="1">
71+
72+
<label for="viscosityInput">Viscosity</label>
73+
<input onchange="gui.sim.viscosity=parseFloat(value)" id="viscosityInput" type="number" value="0.05" step="0.01">
74+
75+
<label for="gravityInput">Gravity</label>
76+
<input onchange="gui.sim.gravity=parseFloat(value)" id="gravityInput" type="number" value="-9.81" step="0.01">
77+
78+
<div class="full-width">
79+
<button onclick="gui.restart()" id="restart">&#9654; Restart</button>
80+
</div>
81+
<div class="full-width">
82+
<button onclick="gui.doPause()" id="Pause" class="btn-secondary">&#9646;&#9646; Pause</button>
83+
</div>
84+
</div>
85+
</div>
9186
</td>
9287
</tr>
93-
<tr><td>
88+
</table>
89+
90+
<!-- Theory section -->
91+
<div class="card theory">
9492
<h2>IISPH algorithm:</h2>
9593
This example shows the IISPH method introduced by Ihmsen et al. [ICS+14]:
9694
<ol>
@@ -185,7 +183,7 @@ <h3>References</h3>
185183
<li>[AIA+12] Nadir Akinci, Markus Ihmsen, Gizem Akinci, Barbara Solenthaler, and Matthias Teschner, "Versatile rigid-fluid coupling for incompressible SPH", ACM Transactions on Graphics 31(4), 2012</li>
186184
</ul>
187185
</td></tr>
188-
</table>
186+
</div>
189187

190188
</main>
191189

@@ -800,8 +798,8 @@ <h3>References</h3>
800798
this.timeSum = 0.0;
801799
this.counter = 0;
802800
this.pause = false;
803-
this.origin = { x : this.canvas.width / 2, y : this.canvas.height/2+200};
804-
this.zoom = 100;
801+
this.origin = { x : this.canvas.width / 2, y : this.canvas.height/2+250};
802+
this.zoom = 120;
805803
this.selectedParticle = -1;
806804

807805
// register mouse event listeners (zoom/selection)
@@ -947,10 +945,12 @@ <h3>References</h3>
947945

948946
getMousePos(canvas, event)
949947
{
950-
let rect = canvas.getBoundingClientRect();
948+
const rect = canvas.getBoundingClientRect();
949+
const scaleX = canvas.width / rect.width; // buffer / displayed size
950+
const scaleY = canvas.height / rect.height;
951951
return {
952-
x: event.clientX - rect.left,
953-
y: event.clientY - rect.top
952+
x: (event.clientX - rect.left) * scaleX,
953+
y: (event.clientY - rect.top) * scaleY
954954
};
955955
}
956956

0 commit comments

Comments
 (0)