prishasinghai commited on
Commit
e627185
Β·
verified Β·
1 Parent(s): 1dc2aff

Create index.html

Browse files
Files changed (1) hide show
  1. index.html +175 -0
index.html ADDED
@@ -0,0 +1,175 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function drawCanvasMap(hamilton, becketts, stowe, gate1Load, isBottleneck) {
2
+ const canvas = document.getElementById('silverstoneCanvas');
3
+ const ctx = canvas.getContext('2d');
4
+
5
+ // Clear canvas background
6
+ ctx.fillStyle = '#181818';
7
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
8
+
9
+ // Map coordinate converter (Scales world grid to canvas pixel positions)
10
+ function toCanvas(x, y) {
11
+ return {
12
+ x: x * 55 + 320,
13
+ y: -y * 45 + 220
14
+ };
15
+ }
16
+
17
+ // -------------------------------------------------------------
18
+ // A. DRAW F1 CIRCUIT TRACK
19
+ // -------------------------------------------------------------
20
+ const trackPoints = [
21
+ {x: 0, y: 0}, {x: 2, y: -2}, {x: 3, y: -3}, {x: 1, y: -3},
22
+ {x: -1, y: -2}, {x: -1, y: 2}, {x: 1, y: 4}, {x: 3, y: 4},
23
+ {x: 4, y: 2}, {x: 2, y: 0}, {x: 0, y: 0}
24
+ ];
25
+
26
+ // Draw outer dark grey track
27
+ ctx.beginPath();
28
+ trackPoints.forEach((pt, idx) => {
29
+ const c = toCanvas(pt.x, pt.y);
30
+ if (idx === 0) ctx.moveTo(c.x, c.y);
31
+ else ctx.lineTo(c.x, c.y);
32
+ });
33
+ ctx.strokeStyle = '#444444';
34
+ ctx.lineWidth = 14;
35
+ ctx.stroke();
36
+
37
+ // Draw center dashed line (racing line)
38
+ ctx.beginPath();
39
+ ctx.setLineDash([6, 6]);
40
+ trackPoints.forEach((pt, idx) => {
41
+ const c = toCanvas(pt.x, pt.y);
42
+ if (idx === 0) ctx.moveTo(c.x, c.y);
43
+ else ctx.lineTo(c.x, c.y);
44
+ });
45
+ ctx.strokeStyle = '#ffffff';
46
+ ctx.lineWidth = 1.5;
47
+ ctx.stroke();
48
+ ctx.setLineDash([]); // Reset dash
49
+
50
+ // -------------------------------------------------------------
51
+ // B. DEFINE MAP NODES (Grandstands, Food Stalls, Gates)
52
+ // -------------------------------------------------------------
53
+ const nodes = {
54
+ "Hamilton GS": { pos: toCanvas(-0.5, 0), type: "gs", label: `Hamilton GS (${hamilton})` },
55
+ "Becketts GS": { pos: toCanvas(1, 3.5), type: "gs", label: `Becketts GS (${becketts})` },
56
+ "Stowe GS": { pos: toCanvas(3.5, 2), type: "gs", label: `Stowe GS (${stowe})` },
57
+ "Main Fan Zone": { pos: toCanvas(0.5, 0.8), type: "food", label: "πŸ” Main Fan Zone" },
58
+ "Becketts Food": { pos: toCanvas(1.8, 3), type: "food", label: "🌭 Becketts Food" },
59
+ "Main Gate 1": { pos: toCanvas(-2.5, 1), type: "gate", label: "πŸšͺ Main Gate 1" },
60
+ "South Gate 2": { pos: toCanvas(1, -4), type: "gate", label: "πŸšͺ South Gate 2" },
61
+ "East Gate 3": { pos: toCanvas(4.5, -1), type: "gate", label: "πŸšͺ East Gate 3" }
62
+ };
63
+
64
+ // -------------------------------------------------------------
65
+ // C. DRAW PEDESTRIAN WALKING PATHS
66
+ // -------------------------------------------------------------
67
+ const paths = [
68
+ { start: "Hamilton GS", end: "Main Fan Zone", color: "#00cc66" },
69
+ { start: "Main Fan Zone", end: "Main Gate 1", color: isBottleneck ? "#ff4444" : "#00cc66" },
70
+ { start: "Becketts GS", end: "Becketts Food", color: "#00cc66" },
71
+ { start: "Becketts Food", end: "Main Gate 1", color: isBottleneck ? "#ff4444" : "#00cc66" },
72
+ { start: "Stowe GS", end: "East Gate 3", color: "#00cc66" },
73
+ { start: "Hamilton GS", end: "South Gate 2", color: "#00cc66" }
74
+ ];
75
+
76
+ paths.forEach(p => {
77
+ ctx.beginPath();
78
+ ctx.moveTo(nodes[p.start].pos.x, nodes[p.start].pos.y);
79
+ ctx.lineTo(nodes[p.end].pos.x, nodes[p.end].pos.y);
80
+ ctx.strokeStyle = p.color;
81
+ ctx.lineWidth = 4;
82
+ ctx.stroke();
83
+ });
84
+
85
+ // -------------------------------------------------------------
86
+ // D. DRAW GOOGLE MAPS PURPLE DETOUR PATH (If Bottlenecked)
87
+ // -------------------------------------------------------------
88
+ if (isBottleneck) {
89
+ ctx.beginPath();
90
+ ctx.setLineDash([8, 8]);
91
+ ctx.moveTo(nodes["Main Fan Zone"].pos.x, nodes["Main Fan Zone"].pos.y);
92
+ ctx.lineTo(nodes["South Gate 2"].pos.x, nodes["South Gate 2"].pos.y);
93
+ ctx.strokeStyle = "#a020f0"; // Purple
94
+ ctx.lineWidth = 5;
95
+ ctx.stroke();
96
+ ctx.setLineDash([]); // Reset dash
97
+ }
98
+
99
+ // -------------------------------------------------------------
100
+ // E. DRAW NODE BOXES AND LABELS
101
+ // -------------------------------------------------------------
102
+ for (let key in nodes) {
103
+ const n = nodes[key];
104
+ ctx.font = "bold 11px Arial";
105
+ const textWidth = ctx.measureText(n.label).width;
106
+ const boxPadding = 8;
107
+
108
+ let boxColor = "#3498db"; // Blue for Grandstand
109
+ if (n.type === "food") boxColor = "#f39c12"; // Orange for Food Court
110
+ if (n.type === "gate") {
111
+ boxColor = (key === "Main Gate 1" && isBottleneck) ? "#ff4444" : "#00cc66";
112
+ }
113
+
114
+ // Draw background rounded box
115
+ ctx.fillStyle = boxColor;
116
+ ctx.beginPath();
117
+ ctx.roundRect(
118
+ n.pos.x - textWidth / 2 - boxPadding,
119
+ n.pos.y - 12,
120
+ textWidth + boxPadding * 2,
121
+ 24,
122
+ 6
123
+ );
124
+ ctx.fill();
125
+ ctx.strokeStyle = "#ffffff";
126
+ ctx.lineWidth = 1;
127
+ ctx.stroke();
128
+
129
+ // Draw white text
130
+ ctx.fillStyle = "#ffffff";
131
+ ctx.textAlign = "center";
132
+ ctx.textBaseline = "middle";
133
+ ctx.fillText(n.label, n.pos.x, n.pos.y);
134
+ }
135
+
136
+ // Draw Legend
137
+ ctx.font = "11px Arial";
138
+ ctx.fillStyle = "#ffffff";
139
+ ctx.textAlign = "left";
140
+ ctx.fillText("🟒 Clear Path", 20, 30);
141
+ ctx.fillText("πŸ”΄ Congested Path", 120, 30);
142
+ ctx.fillText("🟣 Google Maps Detour", 240, 30);
143
+ }
144
+
145
+ function updateReport(gate1, gate2, gate3, isBottleneck, excess, becketts) {
146
+ const reportDiv = document.getElementById('reportBox');
147
+
148
+ if (isBottleneck) {
149
+ reportDiv.className = "report-box alert";
150
+ reportDiv.innerHTML = `
151
+ <h3 style="color: #ff4444;">πŸ”΄ BOTTLENECK ALERT AT MAIN GATE 1</h3>
152
+ <p>β€’ <strong>Gate 1 Load:</strong> <code>${gate1}</code> fans/min (Limit: <code>${GATE_1_CAPACITY}</code>)</p>
153
+ <p>β€’ <strong>Queue Overflow:</strong> <code>${excess}</code> fans facing stampede/delay risks.</p>
154
+ <hr style="border-color: #552222; margin: 10px 0;">
155
+ <h4 style="color: #a020f0;">πŸ”„ Real-Time Optimiser Actions:</h4>
156
+ <p>1. <strong>Google Maps Rerouting:</strong> Diverting <strong>${excess} fans</strong> along the <span class="badge badge-purple">PURPLE DETOUR</span> to <strong>South Gate 2</strong>.</p>
157
+ <p>2. <strong>Zomato Staggering:</strong> Delaying Becketts Grandstand exit calls by <strong>5 minutes</strong> to clear gate pressure.</p>
158
+ `;
159
+ } else {
160
+ reportDiv.className = "report-box";
161
+ reportDiv.innerHTML = `
162
+ <h3 style="color: #00cc66;">🟒 ALL PEDESTRIAN PATHWAYS CLEAR</h3>
163
+ <p>β€’ <strong>Main Gate 1 Load:</strong> <code>${gate1}</code> / ${GATE_1_CAPACITY} fans/min (Safe)</p>
164
+ <p>β€’ <strong>South Gate 2 Load:</strong> <code>${gate2}</code> / 50 fans/min (Safe)</p>
165
+ <p>β€’ <strong>East Gate 3 Load:</strong> <code>${gate3}</code> / 40 fans/min (Safe)</p>
166
+ <p style="margin-top: 5px; color: #aaa;"><em>Status: No dynamic detour required. Crowd flow across grandstands and food stalls is balanced.</em></p>
167
+ `;
168
+ }
169
+ }
170
+
171
+ // Initialize simulation on initial page load
172
+ window.onload = updateSimulation;
173
+ </script>
174
+ </body>
175
+ </html>