<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Histoire, partie 1
En début d'après-midi, le soleil de fin octobre joue avec le garçon et ses amis.Ce n'est pas encore effrayant. Halloween est dans des heures.
( Une communauté d'utilisateurs JMP repensée arrive !La partie 2 et la partie 3 vous y trouveront ! )
Vidéo et code
Cette séquence vidéo montre le recuit simulé pour placer uniformément 3200 points autour d'une sphère.Initialement, les points sont placés dans une double spirale du pôle nord au pôle sud.Je n'essayais pas une double spirale; J'espérais un peu plus de diffusion initiale, mais cela fonctionne quand même.Les couleurs sont juste pour la visualisation.Après les points initiaux, le processus de recuit commence.https://en.wikipedia.org/wiki/Annealing_(métallurgie) décrit un processus de recuit physique, où le métal est chauffé pour détendre une structure cristallisée, permettant aux atomes de se déplacer dans une relation différente.Certains matériaux pourraient même être recuits sous la chaleur du soleil d'octobre.Le JSL ici est peaufiné pour la vidéo et n'est optimisé pour rien d'autre... mais assez bon.Pendant la phase de recuit, un programme de chauffage et de refroidissement contrôle le degré d'éloignement des points par rapport à leur voisin le plus proche.Parce qu'il y a beaucoup de points entassés aux pôles, le calendrier doit maintenir le système chaud pendant un certain temps afin que ces points aient le temps de migrer.A cette « température élevée », les points sautent suffisamment loin pour aller souvent trop loin dans le voisinage d'un autre point.La phase de refroidissement progressif de l'horaire laisse les points s'installer, bougeant de moins en moins.La vidéo se termine avant qu'ils ne soient complètement installés.
https://www.youtube.com/watch?v=8-Fjw1wD-Oc

nnœuds = 3200 ;
xx = -noeuds * 3 / 2 ;
nodelocs = J( nnoeuds, 3, 0 ); // point x,y,z pour chaque nœud
Pour( i = 1, i <= nnœuds, i++,
f = i / nnœuds ; // 0..1
z = Cos( f * Pi() ); // de haut en bas
r = Sin( f * Pi() ); // rayon
x = Sin( 10000 * f ) * r ; // 10 000 radians
y = Cos( 10000 * f ) * r ; // est beaucoup trop.mais ça marche...
nodelocs[i, 1] = x ;
nodelocs[i, 2] = y ;
nodelocs[i, 3] = z ;
);
//nodeobj = scene displaylist(); nodeobj<
addnodes = Function( {thisnnodes},
{inode, delta, pos = [0 0 0], result = Scene Display List()},
For( inode = 1, inode <= thisnnodes, inode++,
delta = nodelocs[inode, 0] - pos ;
pos = nodelocs[inode, 0] ;
//montre(pos,delta);
résultat << translate( delta );
rgb = Couleur vers RVB ( Couleur de chaleur ( inode / nnodes, "spectral" ) ) * 1 ;
//show(inode/nnodes,rgb);
résultat << couleur( rgb[1], rgb[2], rgb[3] );
result << sphere( .005, 3, 3 )//calllist( nodeobj );
;
);
résultat << translate( -pos ); // restaurer l'emplacement d'origine
résultat // renvoie la liste d'affichage
;
);
//a=addnodes();
// anime les nœuds dans une sphère de rayon 1 environ 0,0,0
ajuster = Fonction( {d},
{inode, rayon, le plus proche, dist, err, pos, newlocs = J(nnodes, 3, . ), table = KDTable( nodelocs )},
For( inode = 1, inode <= nnodes, inode++,
pos = nodelocs[inode, 0] ;
// s'éloigner du voisin le plus proche
table << removerows( inode );
{plus proche, dist} = table << knearesrows( 5, pos );
table << insertrows( inode );
Pour( jeferme = 1, jeferme <= 5, jeferme++,
err = pos - nodelocs[plus proche[iclose], 0] + J( 1, 3, Random Normal( 0, .01 ) ); // [dx dz dz]
//pos = pos + .00991/ erreur ; // s'éloigner
Pour( idim = 1, idim <= 3, idim++,
Si( err[idim] < 0,
pos[idim] -= d / fermer,
pos[idim] += d / ifermer
)
);
);
// déplacer le rayon vers 1.000
rayon = Carré( Somme( pos
pos ) );
//err = 1.0 - rayon ; // err est positif si le rayon est trop petit
pos = pos / rayon ; // la grosse erreur se déplace plus vite
newlocs[inode, 0] = pos; // copie temporaire
);
nodelocs = newlocs ; // copie temp en réel
0 // valeur de retour factice
;
);
angle = 30 ;
scène = Scène Boîte( 1924/2, 1084/2 );
build = Function( {thisnnodes},
{},
scène << clair;
scène << ShowArcBall( jamais/*toujours*/ /*Pendant le glissement*/ );
scène << BackgroundColor( noir );
scène << Perspective( 65, .1, 5 );
scène << Translate( 0.0, 0.0, -2.0 );
angle += .1 ;
scène << tourner (angle * 0,23, 1, 0, 0 );
scène << rotation( angle * 0.11, 0, 1, 0 );
scène << tourner (angle * 2, 0, 0, 1 );
objet = addnodes( thisnnodes );
scène << ArcBall( objet, 1 );
);
construire( 1 );
Nouvelle fenêtre( "Dot World", scène );
Pour( je = 1, je <= 3200, je += 4,
construire( je );
scène << mettre à jour ;
Attendez( 0 );
// scene<
);
For( i = 1, i < 5000, i++, // tout sauf fait à 1000
vint = Interpoler( i, 1, .00001, 100, .0005, 200, .001, 4000, .0005, 5000, .00001 );
Show( je, vint );
construire( 3200 );
scène << mettre à jour ;
Attendez( 0 );
ajuster( vint );
//scene<
);
construire();
scène << mettre à jour ;
Attendez( 0 );