(i, count)
| 262 | } |
| 263 | |
| 264 | function createKleinBottle(i, count) { |
| 265 | // Klein Bottle parameters |
| 266 | const a = 15; // Main radius |
| 267 | const b = 4; // Tube radius |
| 268 | const scale = 2.5; // Overall scale |
| 269 | |
| 270 | // Use uniform distribution across the surface |
| 271 | const lengthSteps = Math.ceil(Math.sqrt(count * 0.5)); |
| 272 | const circSteps = Math.ceil(count / lengthSteps); |
| 273 | |
| 274 | // Calculate position in the parametric space |
| 275 | const lengthIndex = i % lengthSteps; |
| 276 | const circIndex = Math.floor(i / lengthSteps) % circSteps; |
| 277 | |
| 278 | // Normalize to appropriate ranges |
| 279 | const u = (lengthIndex / lengthSteps) * Math.PI * 2; // 0 to 2π |
| 280 | const v = (circIndex / circSteps) * Math.PI * 2; // 0 to 2π |
| 281 | |
| 282 | // Klein Bottle parametric equation |
| 283 | let x, y, z; |
| 284 | |
| 285 | // The Klein Bottle has different regions with different parametric equations |
| 286 | if (u < Math.PI) { |
| 287 | // First half (handle and transition region) |
| 288 | x = scale * (a * (1 - Math.cos(u) / 2) * Math.cos(v) - b * Math.sin(u) / 2); |
| 289 | y = scale * (a * (1 - Math.cos(u) / 2) * Math.sin(v)); |
| 290 | z = scale * (a * Math.sin(u) / 2 + b * Math.sin(u) * Math.cos(v)); |
| 291 | } else { |
| 292 | // Second half (main bottle body) |
| 293 | x = scale * (a * (1 + Math.cos(u) / 2) * Math.cos(v) + b * Math.sin(u) / 2); |
| 294 | y = scale * (a * (1 + Math.cos(u) / 2) * Math.sin(v)); |
| 295 | z = scale * (-a * Math.sin(u) / 2 + b * Math.sin(u) * Math.cos(v)); |
| 296 | } |
| 297 | |
| 298 | return new THREE.Vector3(x, y, z); |
| 299 | } |
| 300 | |
| 301 | function createFlower(i, count) { |
| 302 | // Flower/Dandelion parameters |
nothing calls this directly
no outgoing calls
no test coverage detected