lonestar108 commited on
Commit
577768d
·
verified ·
1 Parent(s): 9e5373c

Aparticle sim

Browse files

Particles have x, y, phase, and value
Phase range 0-2PI default to PI +- 5%
Phase controls the degree of attraction/repulsion to other particles. 0 = very attracted to other particles, 2PI = very repulsed from other particles, PI = balanced (both attracted to and repulsed from)
Particles influence the phases of other particles
Particles influence each others phases by formula: (number oof particles * average particle phase) / average distance of particles
But only if the other particle is between a global minimum and max distance
Particles also have a value between 2-100 set when the sim starts.
Particles have second-order attraction to - they are magnetized to - other particles whose values share prime factors with theirs

Files changed (2) hide show
  1. README.md +8 -5
  2. index.html +337 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Phaseflow Particles
3
- emoji: 📚
4
- colorFrom: red
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: PhaseFlow Particles
3
+ colorFrom: yellow
4
+ colorTo: purple
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://deepsite.hf.co).
index.html CHANGED
@@ -1,19 +1,338 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
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>PhaseFlow Particles</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
9
+ <style>
10
+ canvas {
11
+ background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
12
+ }
13
+ .control-panel {
14
+ backdrop-filter: blur(10px);
15
+ background: rgba(15, 23, 42, 0.7);
16
+ }
17
+ </style>
18
+ </head>
19
+ <body class="bg-gray-900 text-white overflow-hidden">
20
+ <div class="relative h-screen w-full">
21
+ <canvas id="particleCanvas" class="absolute top-0 left-0 w-full h-full"></canvas>
22
+
23
+ <!-- Control Panel -->
24
+ <div class="control-panel absolute top-4 right-4 rounded-xl p-4 shadow-lg z-10 w-80">
25
+ <div class="flex justify-between items-center mb-4">
26
+ <h2 class="text-xl font-bold flex items-center">
27
+ <i data-feather="settings" class="mr-2"></i> Controls
28
+ </h2>
29
+ <button id="resetBtn" class="bg-indigo-600 hover:bg-indigo-700 px-3 py-1 rounded-lg text-sm flex items-center">
30
+ <i data-feather="refresh-ccw" class="mr-1"></i> Reset
31
+ </button>
32
+ </div>
33
+
34
+ <div class="space-y-4">
35
+ <div>
36
+ <label class="block text-sm font-medium mb-1">Particle Count: <span id="countValue">150</span></label>
37
+ <input type="range" id="particleCount" min="50" max="300" value="150" class="w-full accent-indigo-500">
38
+ </div>
39
+
40
+ <div>
41
+ <label class="block text-sm font-medium mb-1">Min Distance: <span id="minDistValue">30</span>px</label>
42
+ <input type="range" id="minDistance" min="10" max="100" value="30" class="w-full accent-indigo-500">
43
+ </div>
44
+
45
+ <div>
46
+ <label class="block text-sm font-medium mb-1">Max Distance: <span id="maxDistValue">120</span>px</label>
47
+ <input type="range" id="maxDistance" min="50" max="200" value="120" class="w-full accent-indigo-500">
48
+ </div>
49
+
50
+ <div>
51
+ <label class="block text-sm font-medium mb-1">Interaction Strength: <span id="strengthValue">0.5</span></label>
52
+ <input type="range" id="interactionStrength" min="0.1" max="2" step="0.1" value="0.5" class="w-full accent-indigo-500">
53
+ </div>
54
+
55
+ <div class="flex space-x-2 pt-2">
56
+ <button id="pauseBtn" class="flex-1 bg-amber-600 hover:bg-amber-700 py-2 rounded-lg text-sm flex items-center justify-center">
57
+ <i data-feather="pause" class="mr-1"></i> Pause
58
+ </button>
59
+ <button id="infoBtn" class="flex-1 bg-cyan-600 hover:bg-cyan-700 py-2 rounded-lg text-sm flex items-center justify-center">
60
+ <i data-feather="info" class="mr-1"></i> Info
61
+ </button>
62
+ </div>
63
+ </div>
64
+ </div>
65
+
66
+ <!-- Info Modal -->
67
+ <div id="infoModal" class="hidden fixed inset-0 bg-black bg-opacity-70 z-20 flex items-center justify-center p-4">
68
+ <div class="control-panel rounded-xl p-6 max-w-2xl w-full max-h-[90vh] overflow-y-auto">
69
+ <div class="flex justify-between items-center mb-4">
70
+ <h2 class="text-2xl font-bold">PhaseFlow Simulation</h2>
71
+ <button id="closeInfo" class="text-gray-400 hover:text-white">
72
+ <i data-feather="x"></i>
73
+ </button>
74
+ </div>
75
+ <div class="space-y-4 text-gray-200">
76
+ <p>Each particle has:</p>
77
+ <ul class="list-disc pl-5 space-y-2">
78
+ <li><span class="font-semibold">Position (x, y)</span>: Location on the canvas</li>
79
+ <li><span class="font-semibold">Phase (0-2π)</span>: Controls attraction/repulsion behavior
80
+ <ul class="list-circle pl-5 mt-1">
81
+ <li>0: Strongly attracted</li>
82
+ <li>π: Balanced (attracted & repulsed)</li>
83
+ <li>2π: Strongly repulsed</li>
84
+ </ul>
85
+ </li>
86
+ <li><span class="font-semibold">Value (2-100)</span>: Determines secondary magnetic attraction based on shared prime factors</li>
87
+ </ul>
88
+ <p class="pt-2">Particles influence each other through:</p>
89
+ <ul class="list-disc pl-5 space-y-2">
90
+ <li>Phase interactions within min/max distance range</li>
91
+ <li>Magnetic attraction to particles sharing prime factors</li>
92
+ <li>Phase adjustment formula: (particle count × average phase) / average distance</li>
93
+ </ul>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+
99
+ <script>
100
+ // Initialize feather icons
101
+ feather.replace();
102
+
103
+ // Canvas setup
104
+ const canvas = document.getElementById('particleCanvas');
105
+ const ctx = canvas.getContext('2d');
106
+ canvas.width = window.innerWidth;
107
+ canvas.height = window.innerHeight;
108
+
109
+ // Simulation parameters
110
+ let params = {
111
+ particleCount: 150,
112
+ minDistance: 30,
113
+ maxDistance: 120,
114
+ interactionStrength: 0.5,
115
+ paused: false
116
+ };
117
+
118
+ // Particle class
119
+ class Particle {
120
+ constructor(x, y) {
121
+ this.x = x || Math.random() * canvas.width;
122
+ this.y = y || Math.random() * canvas.height;
123
+ this.phase = Math.PI + (Math.random() * 0.1 - 0.05); // PI ± 5%
124
+ this.value = Math.floor(Math.random() * 99) + 2; // 2-100
125
+ this.vx = (Math.random() - 0.5) * 0.5;
126
+ this.vy = (Math.random() - 0.5) * 0.5;
127
+ this.radius = 3 + (this.value / 30);
128
+ this.color = this.getPhaseColor();
129
+ this.primeFactors = this.getPrimeFactors(this.value);
130
+ }
131
+
132
+ getPrimeFactors(n) {
133
+ const factors = [];
134
+ let divisor = 2;
135
+ while (n >= 2) {
136
+ if (n % divisor === 0) {
137
+ factors.push(divisor);
138
+ n = n / divisor;
139
+ } else {
140
+ divisor++;
141
+ }
142
+ }
143
+ return [...new Set(factors)]; // Unique factors
144
+ }
145
+
146
+ getPhaseColor() {
147
+ // Map phase to color: 0=blue, π=green, 2π=red
148
+ const hue = (this.phase / (2 * Math.PI)) * 360;
149
+ return `hsl(${hue}, 80%, 60%)`;
150
+ }
151
+
152
+ update(particles) {
153
+ if (params.paused) return;
154
+
155
+ // Apply velocity
156
+ this.x += this.vx;
157
+ this.y += this.vy;
158
+
159
+ // Boundary conditions
160
+ if (this.x < 0) this.x = canvas.width;
161
+ if (this.x > canvas.width) this.x = 0;
162
+ if (this.y < 0) this.y = canvas.height;
163
+ if (this.y > canvas.height) this.y = 0;
164
+
165
+ // Interaction calculations
166
+ let fx = 0;
167
+ let fy = 0;
168
+ let nearbyParticles = 0;
169
+ let totalPhase = 0;
170
+ let totalDistance = 0;
171
+
172
+ for (let other of particles) {
173
+ if (other === this) continue;
174
+
175
+ const dx = other.x - this.x;
176
+ const dy = other.y - this.y;
177
+ const distance = Math.sqrt(dx * dx + dy * dy);
178
+
179
+ if (distance > params.minDistance && distance < params.maxDistance) {
180
+ // Primary phase-based force
181
+ const force = Math.cos(this.phase) * params.interactionStrength / distance;
182
+ fx += force * dx;
183
+ fy += force * dy;
184
+
185
+ // Collect data for phase influence
186
+ nearbyParticles++;
187
+ totalPhase += other.phase;
188
+ totalDistance += distance;
189
+
190
+ // Secondary magnetic attraction based on shared prime factors
191
+ const sharedFactors = this.primeFactors.filter(factor =>
192
+ other.primeFactors.includes(factor));
193
+
194
+ if (sharedFactors.length > 0) {
195
+ const magneticForce = sharedFactors.length * 0.05 / distance;
196
+ this.vx += magneticForce * dx * 0.01;
197
+ this.vy += magneticForce * dy * 0.01;
198
+ }
199
+ }
200
+ }
201
+
202
+ // Apply phase influence from nearby particles
203
+ if (nearbyParticles > 0) {
204
+ const avgPhase = totalPhase / nearbyParticles;
205
+ const avgDistance = totalDistance / nearbyParticles;
206
+ const phaseInfluence = (nearbyParticles * avgPhase) / avgDistance * 0.01;
207
+ this.phase = (this.phase + phaseInfluence) % (2 * Math.PI);
208
+ if (this.phase < 0) this.phase += 2 * Math.PI;
209
+ }
210
+
211
+ // Apply forces
212
+ this.vx += fx * 0.01;
213
+ this.vy += fy * 0.01;
214
+
215
+ // Velocity damping
216
+ this.vx *= 0.99;
217
+ this.vy *= 0.99;
218
+
219
+ // Update color based on new phase
220
+ this.color = this.getPhaseColor();
221
+ }
222
+
223
+ draw() {
224
+ ctx.beginPath();
225
+ ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
226
+ ctx.fillStyle = this.color;
227
+ ctx.fill();
228
+
229
+ // Draw value indicator
230
+ ctx.beginPath();
231
+ ctx.arc(this.x, this.y, this.radius * 0.4, 0, Math.PI * 2);
232
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
233
+ ctx.fill();
234
+ }
235
+ }
236
+
237
+ // Create particles
238
+ let particles = [];
239
+ function initParticles() {
240
+ particles = [];
241
+ for (let i = 0; i < params.particleCount; i++) {
242
+ particles.push(new Particle());
243
+ }
244
+ }
245
+
246
+ // Animation loop
247
+ function animate() {
248
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
249
+
250
+ // Draw connections between close particles
251
+ ctx.lineWidth = 0.5;
252
+ for (let i = 0; i < particles.length; i++) {
253
+ for (let j = i + 1; j < particles.length; j++) {
254
+ const p1 = particles[i];
255
+ const p2 = particles[j];
256
+ const dx = p1.x - p2.x;
257
+ const dy = p1.y - p2.y;
258
+ const dist = Math.sqrt(dx * dx + dy * dy);
259
+
260
+ if (dist < params.maxDistance) {
261
+ const alpha = 1 - dist / params.maxDistance;
262
+ ctx.strokeStyle = `rgba(100, 150, 255, ${alpha * 0.2})`;
263
+ ctx.beginPath();
264
+ ctx.moveTo(p1.x, p1.y);
265
+ ctx.lineTo(p2.x, p2.y);
266
+ ctx.stroke();
267
+ }
268
+ }
269
+ }
270
+
271
+ // Update and draw particles
272
+ particles.forEach(particle => {
273
+ particle.update(particles);
274
+ particle.draw();
275
+ });
276
+
277
+ requestAnimationFrame(animate);
278
+ }
279
+
280
+ // Event listeners for controls
281
+ document.getElementById('particleCount').addEventListener('input', function() {
282
+ params.particleCount = parseInt(this.value);
283
+ document.getElementById('countValue').textContent = this.value;
284
+ initParticles();
285
+ });
286
+
287
+ document.getElementById('minDistance').addEventListener('input', function() {
288
+ params.minDistance = parseInt(this.value);
289
+ document.getElementById('minDistValue').textContent = this.value;
290
+ });
291
+
292
+ document.getElementById('maxDistance').addEventListener('input', function() {
293
+ params.maxDistance = parseInt(this.value);
294
+ document.getElementById('maxDistValue').textContent = this.value;
295
+ });
296
+
297
+ document.getElementById('interactionStrength').addEventListener('input', function() {
298
+ params.interactionStrength = parseFloat(this.value);
299
+ document.getElementById('strengthValue').textContent = this.value;
300
+ });
301
+
302
+ document.getElementById('pauseBtn').addEventListener('click', function() {
303
+ params.paused = !params.paused;
304
+ const icon = this.querySelector('i');
305
+ if (params.paused) {
306
+ icon.setAttribute('data-feather', 'play');
307
+ this.innerHTML = '<i data-feather="play" class="mr-1"></i> Resume';
308
+ } else {
309
+ icon.setAttribute('data-feather', 'pause');
310
+ this.innerHTML = '<i data-feather="pause" class="mr-1"></i> Pause';
311
+ }
312
+ feather.replace();
313
+ });
314
+
315
+ document.getElementById('resetBtn').addEventListener('click', function() {
316
+ initParticles();
317
+ });
318
+
319
+ document.getElementById('infoBtn').addEventListener('click', function() {
320
+ document.getElementById('infoModal').classList.remove('hidden');
321
+ });
322
+
323
+ document.getElementById('closeInfo').addEventListener('click', function() {
324
+ document.getElementById('infoModal').classList.add('hidden');
325
+ });
326
+
327
+ // Handle window resize
328
+ window.addEventListener('resize', function() {
329
+ canvas.width = window.innerWidth;
330
+ canvas.height = window.innerHeight;
331
+ });
332
+
333
+ // Initialize and start simulation
334
+ initParticles();
335
+ animate();
336
+ </script>
337
+ </body>
338
  </html>