statisticalplumber commited on
Commit
b5137ae
·
verified ·
1 Parent(s): 56ab29d

Create app1/index.html

Browse files
Files changed (1) hide show
  1. app1/index.html +527 -0
app1/index.html ADDED
@@ -0,0 +1,527 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Lotka-Volterra Predator-Prey Simulation</title>
7
+ <style>
8
+ body {
9
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10
+ max-width: 1000px;
11
+ margin: 0 auto;
12
+ padding: 20px;
13
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
14
+ color: #333;
15
+ }
16
+ h1 {
17
+ text-align: center;
18
+ color: #2c3e50;
19
+ margin-bottom: 10px;
20
+ text-shadow: 0 2px 4px rgba(0,0,0,0.1);
21
+ }
22
+ h2 {
23
+ color: #3498db;
24
+ margin-top: 30px;
25
+ }
26
+ .container {
27
+ background-color: white;
28
+ padding: 25px;
29
+ border-radius: 12px;
30
+ box-shadow: 0 8px 30px rgba(0,0,0,0.15);
31
+ margin-bottom: 20px;
32
+ }
33
+ .description {
34
+ background-color: #e3f2fd;
35
+ padding: 15px;
36
+ border-radius: 8px;
37
+ margin-bottom: 20px;
38
+ border-left: 4px solid #3498db;
39
+ }
40
+ canvas {
41
+ border: 1px solid #ddd;
42
+ margin-top: 20px;
43
+ background-color: #f9f9f9;
44
+ border-radius: 8px;
45
+ }
46
+ .controls {
47
+ display: flex;
48
+ flex-wrap: wrap;
49
+ gap: 20px;
50
+ margin-top: 25px;
51
+ }
52
+ .control-group {
53
+ flex: 1;
54
+ min-width: 200px;
55
+ background-color: #f8f9fa;
56
+ padding: 15px;
57
+ border-radius: 8px;
58
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
59
+ }
60
+ .control-group h3 {
61
+ margin-top: 0;
62
+ color: #2c3e50;
63
+ border-bottom: 1px solid #eee;
64
+ padding-bottom: 8px;
65
+ }
66
+ label {
67
+ display: block;
68
+ margin-bottom: 8px;
69
+ font-weight: 600;
70
+ color: #2c3e50;
71
+ }
72
+ input[type="range"] {
73
+ width: 100%;
74
+ margin-bottom: 5px;
75
+ }
76
+ .value-display {
77
+ text-align: right;
78
+ font-size: 14px;
79
+ color: #7f8c8d;
80
+ font-weight: bold;
81
+ }
82
+ .initial-controls {
83
+ display: flex;
84
+ gap: 15px;
85
+ margin-top: 10px;
86
+ }
87
+ .initial-controls input {
88
+ flex: 1;
89
+ padding: 8px;
90
+ border-radius: 4px;
91
+ border: 1px solid #ddd;
92
+ }
93
+ button {
94
+ background-color: #3498db;
95
+ color: white;
96
+ border: none;
97
+ padding: 12px 20px;
98
+ border-radius: 6px;
99
+ cursor: pointer;
100
+ font-weight: bold;
101
+ margin-top: 15px;
102
+ width: 100%;
103
+ font-size: 16px;
104
+ transition: all 0.3s ease;
105
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
106
+ }
107
+ button:hover {
108
+ background-color: #2980b9;
109
+ transform: translateY(-2px);
110
+ box-shadow: 0 4px 8px rgba(0,0,0,0.15);
111
+ }
112
+ .legend {
113
+ display: flex;
114
+ justify-content: center;
115
+ gap: 20px;
116
+ margin-top: 15px;
117
+ }
118
+ .legend-item {
119
+ display: flex;
120
+ align-items: center;
121
+ gap: 5px;
122
+ }
123
+ .legend-color {
124
+ width: 15px;
125
+ height: 15px;
126
+ border-radius: 3px;
127
+ }
128
+ .help-section {
129
+ background-color: #fff8e1;
130
+ padding: 20px;
131
+ border-radius: 8px;
132
+ margin-top: 25px;
133
+ border-left: 4px solid #f39c12;
134
+ }
135
+ .help-section h3 {
136
+ margin-top: 0;
137
+ color: #e67e22;
138
+ }
139
+ .variable {
140
+ display: flex;
141
+ margin-bottom: 10px;
142
+ padding: 8px;
143
+ background-color: #fff;
144
+ border-radius: 4px;
145
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
146
+ }
147
+ .variable-name {
148
+ font-weight: bold;
149
+ color: #2c3e50;
150
+ min-width: 140px;
151
+ }
152
+ .variable-desc {
153
+ flex: 1;
154
+ }
155
+ .equation {
156
+ background-color: #f8f9fa;
157
+ padding: 10px;
158
+ border-radius: 6px;
159
+ margin: 15px 0;
160
+ font-family: monospace;
161
+ text-align: center;
162
+ border-left: 3px solid #3498db;
163
+ }
164
+ </style>
165
+ </head>
166
+ <body>
167
+ <div class="container">
168
+ <h1>Lotka-Volterra Predator-Prey Simulation</h1>
169
+
170
+ <div class="description">
171
+ <p>This simulation demonstrates the classic Lotka-Volterra model of predator-prey dynamics. The populations of prey and predators oscillate in a cyclical pattern based on the mathematical relationships between their growth rates, predation, and death rates.</p>
172
+ </div>
173
+
174
+ <canvas id="simulationCanvas" width="800" height="400"></canvas>
175
+
176
+ <div class="legend">
177
+ <div class="legend-item">
178
+ <div class="legend-color" style="background-color: #3498db;"></div>
179
+ <span>Prey Population</span>
180
+ </div>
181
+ <div class="legend-item">
182
+ <div class="legend-color" style="background-color: #e74c3c;"></div>
183
+ <span>Predator Population</span>
184
+ </div>
185
+ </div>
186
+
187
+ <div class="controls">
188
+ <div class="control-group">
189
+ <h3>Population Parameters</h3>
190
+
191
+ <label for="initialPrey">Initial Prey Population: <span id="initialPreyValue">40</span></label>
192
+ <input type="range" id="initialPrey" min="1" max="200" step="1" value="40">
193
+
194
+ <label for="initialPredator">Initial Predator Population: <span id="initialPredatorValue">9</span></label>
195
+ <input type="range" id="initialPredator" min="1" max="50" step="1" value="9">
196
+
197
+ <div class="initial-controls">
198
+ <input type="number" id="preyInput" min="1" max="200" value="40">
199
+ <input type="number" id="predatorInput" min="1" max="50" value="9">
200
+ </div>
201
+ </div>
202
+
203
+ <div class="control-group">
204
+ <h3>Environmental Parameters</h3>
205
+
206
+ <label for="preyRate">Prey Reproduction Rate: <span id="preyRateValue">0.1</span></label>
207
+ <input type="range" id="preyRate" min="0.01" max="0.5" step="0.01" value="0.1">
208
+
209
+ <label for="predationRate">Predation Rate: <span id="predationRateValue">0.01</span></label>
210
+ <input type="range" id="predationRate" min="0.001" max="0.1" step="0.001" value="0.01">
211
+
212
+ <label for="predatorDeathRate">Predator Death Rate: <span id="predatorDeathRateValue">0.1</span></label>
213
+ <input type="range" id="predatorDeathRate" min="0.01" max="0.5" step="0.01" value="0.1">
214
+
215
+ <label for="predatorEfficiency">Predator Efficiency: <span id="predatorEfficiencyValue">0.01</span></label>
216
+ <input type="range" id="predatorEfficiency" min="0.001" max="0.1" step="0.001" value="0.01">
217
+ </div>
218
+ </div>
219
+
220
+ <button id="resetBtn">Reset Simulation</button>
221
+ </div>
222
+
223
+ <div class="help-section">
224
+ <h3>Lotka-Volterra Model Variables</h3>
225
+
226
+ <div class="variable">
227
+ <div class="variable-name">X (Prey)</div>
228
+ <div class="variable-desc">Population of prey species. Increases when not being eaten and decreases due to predation.</div>
229
+ </div>
230
+
231
+ <div class="variable">
232
+ <div class="variable-name">Y (Predator)</div>
233
+ <div class="variable-desc">Population of predator species. Increases when consuming prey and decreases due to natural death.</div>
234
+ </div>
235
+
236
+ <div class="variable">
237
+ <div class="variable-name">α</div>
238
+ <div class="variable-desc">Prey reproduction rate. Determines how quickly prey population grows in the absence of predators.</div>
239
+ </div>
240
+
241
+ <div class="variable">
242
+ <div class="variable-name">β</div>
243
+ <div class="variable-desc">Predation rate. Determines how effectively predators consume prey.</div>
244
+ </div>
245
+
246
+ <div class="variable">
247
+ <div class="variable-name">γ</div>
248
+ <div class="variable-desc">Predator death rate. Determines how quickly predators die in the absence of prey.</div>
249
+ </div>
250
+
251
+ <div class="variable">
252
+ <div class="variable-name">δ</div>
253
+ <div class="variable-desc">Predator efficiency. Determines how effectively predators convert consumed prey into predator offspring.</div>
254
+ </div>
255
+
256
+ <h3>Mathematical Equations</h3>
257
+ <div class="equation">dX/dt = αX - βXY</div>
258
+ <div class="equation">dY/dt = δXY - γY</div>
259
+
260
+ <h3>How to Use This Simulation</h3>
261
+ <p>This simulation shows the oscillating relationship between prey and predator populations. Adjust parameters to see how they affect population dynamics:</p>
262
+ <ul>
263
+ <li>Higher prey reproduction rate (α) leads to faster prey population growth</li>
264
+ <li>Higher predation rate (β) causes more rapid decline in prey population</li>
265
+ <li>Higher predator death rate (γ) causes faster predator decline when prey is scarce</li>
266
+ <li>Higher predator efficiency (δ) allows predators to grow faster when prey is abundant</li>
267
+ </ul>
268
+ </div>
269
+
270
+ <script>
271
+ // Canvas setup
272
+ const canvas = document.getElementById('simulationCanvas');
273
+ const ctx = canvas.getContext('2d');
274
+
275
+ // Simulation parameters
276
+ let params = {
277
+ preyRate: 0.1,
278
+ predationRate: 0.01,
279
+ predatorDeathRate: 0.1,
280
+ predatorEfficiency: 0.01
281
+ };
282
+
283
+ // Initial populations with user controls
284
+ let preyPopulation = 40;
285
+ let predatorPopulation = 9;
286
+
287
+ // Simulation variables
288
+ const dt = 0.01; // Time step
289
+ let time = 0;
290
+ const maxTime = 50;
291
+
292
+ // History arrays for plotting
293
+ let preyHistory = [];
294
+ let predatorHistory = [];
295
+ let timeHistory = [];
296
+
297
+ // Update value displays
298
+ function updateValueDisplays() {
299
+ document.getElementById('preyRateValue').textContent = params.preyRate.toFixed(2);
300
+ document.getElementById('predationRateValue').textContent = params.predationRate.toFixed(3);
301
+ document.getElementById('predatorDeathRateValue').textContent = params.predatorDeathRate.toFixed(2);
302
+ document.getElementById('predatorEfficiencyValue').textContent = params.predatorEfficiency.toFixed(3);
303
+ document.getElementById('initialPreyValue').textContent = preyPopulation;
304
+ document.getElementById('initialPredatorValue').textContent = predatorPopulation;
305
+ }
306
+
307
+ // Update parameters from sliders
308
+ function updateParams() {
309
+ params.preyRate = parseFloat(document.getElementById('preyRate').value);
310
+ params.predationRate = parseFloat(document.getElementById('predationRate').value);
311
+ params.predatorDeathRate = parseFloat(document.getElementById('predatorDeathRate').value);
312
+ params.predatorEfficiency = parseFloat(document.getElementById('predatorEfficiency').value);
313
+
314
+ updateValueDisplays();
315
+ }
316
+
317
+ // Update initial populations from inputs
318
+ function updateInitialPopulations() {
319
+ const preyInput = document.getElementById('preyInput');
320
+ const predatorInput = document.getElementById('predatorInput');
321
+
322
+ if (preyInput.value >= 1 && preyInput.value <= 200) {
323
+ preyPopulation = parseInt(preyInput.value);
324
+ }
325
+
326
+ if (predatorInput.value >= 1 && predatorInput.value <= 50) {
327
+ predatorPopulation = parseInt(predatorInput.value);
328
+ }
329
+
330
+ updateValueDisplays();
331
+ }
332
+
333
+ // Lotka-Volterra equations
334
+ function calculatePopulations() {
335
+ const prey = preyPopulation;
336
+ const predator = predatorPopulation;
337
+
338
+ // Calculate rates of change
339
+ const dPrey = params.preyRate * prey - params.predationRate * prey * predator;
340
+ const dPredator = params.predatorEfficiency * params.predationRate * prey * predator - params.predatorDeathRate * predator;
341
+
342
+ // Update populations
343
+ preyPopulation += dPrey * dt;
344
+ predatorPopulation += dPredator * dt;
345
+
346
+ // Ensure populations don't go negative
347
+ preyPopulation = Math.max(0, preyPopulation);
348
+ predatorPopulation = Math.max(0, predatorPopulation);
349
+
350
+ // Store history for plotting
351
+ timeHistory.push(time);
352
+ preyHistory.push(preyPopulation);
353
+ predatorHistory.push(predatorPopulation);
354
+
355
+ time += dt;
356
+ }
357
+
358
+ // Draw the simulation
359
+ function drawSimulation() {
360
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
361
+
362
+ // Draw axes
363
+ ctx.beginPath();
364
+ ctx.strokeStyle = '#95a5a6';
365
+ ctx.lineWidth = 1;
366
+
367
+ // X-axis
368
+ ctx.moveTo(50, canvas.height - 50);
369
+ ctx.lineTo(canvas.width - 50, canvas.height - 50);
370
+
371
+ // Y-axis
372
+ ctx.moveTo(50, 50);
373
+ ctx.lineTo(50, canvas.height - 50);
374
+
375
+ ctx.stroke();
376
+
377
+ // Draw labels
378
+ ctx.fillStyle = '#2c3e50';
379
+ ctx.font = '14px Arial';
380
+ ctx.fillText('Time', canvas.width/2, canvas.height - 20);
381
+ ctx.save();
382
+ ctx.translate(15, canvas.height/2);
383
+ ctx.rotate(-Math.PI/2);
384
+ ctx.fillText('Population', 0, 0);
385
+ ctx.restore();
386
+
387
+ // Draw grid
388
+ ctx.strokeStyle = '#ecf0f1';
389
+ ctx.lineWidth = 0.5;
390
+
391
+ // Vertical grid lines
392
+ for (let i = 1; i < 10; i++) {
393
+ const x = 50 + (i * (canvas.width - 100) / 10);
394
+ ctx.beginPath();
395
+ ctx.moveTo(x, 50);
396
+ ctx.lineTo(x, canvas.height - 50);
397
+ ctx.stroke();
398
+ }
399
+
400
+ // Horizontal grid lines
401
+ for (let i = 1; i < 5; i++) {
402
+ const y = 50 + (i * (canvas.height - 100) / 5);
403
+ ctx.beginPath();
404
+ ctx.moveTo(50, y);
405
+ ctx.lineTo(canvas.width - 50, y);
406
+ ctx.stroke();
407
+ }
408
+
409
+ // Scale populations for drawing
410
+ const maxPrey = Math.max(...preyHistory, preyPopulation) * 1.2;
411
+ const maxPredator = Math.max(...predatorHistory, predatorPopulation) * 1.2;
412
+
413
+ // Draw population curves
414
+ ctx.beginPath();
415
+ ctx.strokeStyle = '#3498db';
416
+ ctx.lineWidth = 2;
417
+
418
+ // Draw prey curve
419
+ for (let i = 0; i < preyHistory.length; i++) {
420
+ const x = 50 + (timeHistory[i] / maxTime) * (canvas.width - 100);
421
+ const y = canvas.height - 50 - (preyHistory[i] / maxPrey) * (canvas.height - 100);
422
+ if (i === 0) {
423
+ ctx.moveTo(x, y);
424
+ } else {
425
+ ctx.lineTo(x, y);
426
+ }
427
+ }
428
+
429
+ // Draw predator curve
430
+ ctx.strokeStyle = '#e74c3c';
431
+ for (let i = 0; i < predatorHistory.length; i++) {
432
+ const x = 50 + (timeHistory[i] / maxTime) * (canvas.width - 100);
433
+ const y = canvas.height - 50 - (predatorHistory[i] / maxPredator) * (canvas.height - 100);
434
+ if (i === 0) {
435
+ ctx.moveTo(x, y);
436
+ } else {
437
+ ctx.lineTo(x, y);
438
+ }
439
+ }
440
+
441
+ ctx.stroke();
442
+
443
+ // Draw current populations
444
+ const preyX = 50 + (time / maxTime) * (canvas.width - 100);
445
+ const preyY = canvas.height - 50 - (preyPopulation / maxPrey) * (canvas.height - 100);
446
+ const predatorX = 50 + (time / maxTime) * (canvas.width - 100);
447
+ const predatorY = canvas.height - 50 - (predatorPopulation / maxPredator) * (canvas.height - 100);
448
+
449
+ // Draw dots
450
+ ctx.fillStyle = '#3498db';
451
+ ctx.beginPath();
452
+ ctx.arc(preyX, preyY, 5, 0, Math.PI * 2);
453
+ ctx.fill();
454
+
455
+ ctx.fillStyle = '#e74c3c';
456
+ ctx.beginPath();
457
+ ctx.arc(predatorX, predatorY, 5, 0, Math.PI * 2);
458
+ ctx.fill();
459
+
460
+ // Draw population values
461
+ ctx.fillStyle = '#3498db';
462
+ ctx.font = '12px Arial';
463
+ ctx.fillText(`Prey: ${preyPopulation.toFixed(0)}`, preyX + 10, preyY - 10);
464
+
465
+ ctx.fillStyle = '#e74c3c';
466
+ ctx.fillText(`Predator: ${predatorPopulation.toFixed(0)}`, predatorX + 10, predatorY - 10);
467
+ }
468
+
469
+ // Reset simulation
470
+ function resetSimulation() {
471
+ time = 0;
472
+ preyHistory = [];
473
+ predatorHistory = [];
474
+ timeHistory = [];
475
+ }
476
+
477
+ // Animation loop
478
+ function animate() {
479
+ calculatePopulations();
480
+ drawSimulation();
481
+
482
+ if (time < maxTime) {
483
+ requestAnimationFrame(animate);
484
+ } else {
485
+ // Restart simulation when it completes
486
+ resetSimulation();
487
+ animate();
488
+ }
489
+ }
490
+
491
+ // Initialize event listeners
492
+ document.getElementById('preyRate').addEventListener('input', updateParams);
493
+ document.getElementById('predationRate').addEventListener('input', updateParams);
494
+ document.getElementById('predatorDeathRate').addEventListener('input', updateParams);
495
+ document.getElementById('predatorEfficiency').addEventListener('input', updateParams);
496
+
497
+ // Handle initial population inputs
498
+ document.getElementById('initialPrey').addEventListener('input', function() {
499
+ const value = parseInt(this.value);
500
+ document.getElementById('preyInput').value = value;
501
+ preyPopulation = value;
502
+ updateValueDisplays();
503
+ });
504
+
505
+ document.getElementById('initialPredator').addEventListener('input', function() {
506
+ const value = parseInt(this.value);
507
+ document.getElementById('predatorInput').value = value;
508
+ predatorPopulation = value;
509
+ updateValueDisplays();
510
+ });
511
+
512
+ document.getElementById('preyInput').addEventListener('change', updateInitialPopulations);
513
+ document.getElementById('predatorInput').addEventListener('change', updateInitialPopulations);
514
+
515
+ document.getElementById('resetBtn').addEventListener('click', function() {
516
+ resetSimulation();
517
+ animate();
518
+ });
519
+
520
+ // Initialize displays
521
+ updateValueDisplays();
522
+
523
+ // Start simulation
524
+ animate();
525
+ </script>
526
+ </body>
527
+ </html>