Aller au contenu principal

Attracteur de Rössler

Ouvrir l'attracteur de Rössler. Faites glisser la souris pour étudier le portrait de phase sous tous les angles. Le curseur modifie le paramètre de bifurcation cc entre 3 et 12 et le bouton lecture/pause permet d'immobiliser le déplacement des marqueurs.

Le Système Dynamique​

Introduit par Otto Rössler en 1976, ce système continu modélise un comportement chaotique avec un couplage non linéaire minimal :

x˙=−y−z,y˙=x+ay,z˙=b+z(x−c).\dot{x} = -y - z,\qquad \dot{y} = x + ay,\qquad \dot{z} = b + z(x - c).

Les paramètres initiaux standards sont a=0,2a = 0{,}2, b=0,2b = 0{,}2 et c=5,7c = 5{,}7. Dans le plan (x,y)(x, y), le système effectue une rotation oscillante d’amplitude croissante. Lorsque xx dépasse le seuil cc, le terme non linéaire z(x−c)z(x - c) éjecte brutalement la trajectoire dans la troisième dimension avant qu'elle ne se replie en spirale. Ce retour au plan spiralé forme un espace des phases à une seule bande repliée.

Faire varier cc conduit à des bifurcations par doublement de période, avec des bandes chaotiques et des orbites périodiques de structures différentes.

Intégration par Runge–Kutta 4 (RK4)​

L'intégration d'Euler présente une erreur de troncature du premier ordre. Dans les régimes chaotiques, elle accumule trop d'erreurs et efface les détails de l’espace des phases. Le système utilise donc l'algorithme RK4 avec un pas Δt=0,01\Delta t = 0{,}01 :

function derivative(x, y, z, {a, b, c}) {
return [-y - z, x + a * y, b + z * (x - c)];
}

function rk4Step([x, y, z], parameters) {
const {dt} = parameters;
const k1 = derivative(x, y, z, parameters);
const k2 = derivative(x + (dt * k1[0]) / 2, y + (dt * k1[1]) / 2, z + (dt * k1[2]) / 2, parameters);
const k3 = derivative(x + (dt * k2[0]) / 2, y + (dt * k2[1]) / 2, z + (dt * k2[2]) / 2, parameters);
const k4 = derivative(x + dt * k3[0], y + dt * k3[1], z + dt * k3[2], parameters);

return [
x + (dt * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0])) / 6,
y + (dt * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1])) / 6,
z + (dt * (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2])) / 6,
];
}

L’ordre d’erreur de RK4, sa région de stabilité et les vérifications par réduction du pas sont présentés dans Résoudre les EDO numériquement.

Depuis l’état initial (0,1,0,0)(0{,}1, 0, 0), 3 000 pas préliminaires sont effectués puis écartés pour éliminer le régime transitoire initial avant d'enregistrer 28 000 points, afin de reconstruire la spirale et ses replis.

Géométrie et Rendu Tubulaire​

Dessiner directement les 28 000 points avec des lignes d’un pixel donnerait peu de profondeur ou de volume. Les points sont sous-échantillonnés, recentrés et interpolés par une courbe Catmull–Rom pour générer un tube 3D (TubeGeometry) avec couleurs spectrales aux sommets :

const positions = generateRosslerTrajectory({c: parameter, sampleCount: 28000});
const vertices = [];

// Échantillonner un point sur 6 (pas de 18 dans le tableau plat) pour équilibrer précision et coût
for (let i = 0; i < positions.length; i += 18) {
vertices.push(new THREE.Vector3().fromArray(positions, i));
}

// Centrer la géométrie de la trajectoire pour que la rotation pivote autour du centre de sa boîte englobante
const box = new THREE.Box3().setFromPoints(vertices);
const center = box.getCenter(new THREE.Vector3());
vertices.forEach((v) => v.sub(center));

const curve = new THREE.CatmullRomCurve3(vertices);
const segments = 4800;
const geometry = new THREE.TubeGeometry(curve, segments, 0.12, 5, false);

// Attribuer des couleurs spectrales aux sommets le long de l’arc
const SPECTRUM = ['#337dcc', '#28a5a0', '#b1b748', '#ecaa38', '#e26743', '#b766ac', '#337dcc'];
const stops = SPECTRUM.map((c) => new THREE.Color(c));
const colors = new Float32Array(geometry.attributes.position.count * 3);
const color = new THREE.Color();

for (let i = 0; i < colors.length / 3; i++) {
const t = Math.floor(i / 6) / segments * (stops.length - 1);
const k = Math.min(Math.floor(t), stops.length - 2);
color.copy(stops[k]).lerp(stops[k + 1], t - k).toArray(colors, i * 3);
}
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const material = new THREE.MeshBasicMaterial({vertexColors: true});

Les couleurs évoluent dans l’ordre temporel de la trajectoire et rendent son sens de parcours plus lisible.

Marqueurs instanciés et contours contrastés​

Douze marqueurs lumineux parcourent la courbe interpolée à vitesse constante selon la longueur d’arc. Deux groupes THREE.InstancedMesh évitent de créer douze ensembles de meshes :

  1. Des sphères lumineuses internes (color: '#fff2bc').
  2. Des coques sombres externes (color: '#191a16', side: THREE.BackSide), agrandies d’un facteur 1,4.
const beadCount = 12;
const beadGeometry = new THREE.SphereGeometry(0.36, 12, 8);
const beadMaterial = new THREE.MeshBasicMaterial({color: '#fff2bc'});
const outlineMaterial = new THREE.MeshBasicMaterial({color: '#191a16', side: THREE.BackSide});

const beads = new THREE.InstancedMesh(beadGeometry, beadMaterial, beadCount);
const outlines = new THREE.InstancedMesh(beadGeometry, outlineMaterial, beadCount);

// Désactiver le culling pour que les marqueurs parcourent toute la courbe sans être masqués à tort
beads.frustumCulled = false;
outlines.frustumCulled = false;

Des sphères instanciées (InstancedMesh) parcourent le ruban avec une silhouette sombre garantissant leur lisibilité sur fond clair comme sur fond sombre. Ce contour à normales inversées reste visible même lorsque les marqueurs se superposent aux zones claires du tube.

Limites de performance et libération des ressources​

  • Cadence limitée : les horodatages plafonnent le rendu à 30 FPS pour éviter une activité GPU inutile sur les écrans à haute fréquence.
  • Arrêt hors champ : les demandes de trames d’animation cessent complètement lorsque le conteneur quitte la zone visible ou que l’onglet passe en arrière-plan.
  • Nettoyage : au démontage ou lors d’un changement de paramètres, le composant appelle .dispose() sur les géométries, les matériaux, les deux objets InstancedMesh et les contrôles ; il déconnecte les observateurs, puis libère le moteur de rendu WebGL et son contexte.
Explorer les liensOuvrir le réseau