<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />ストーリー、パート1
午後の早い時間に、10月下旬の太陽の光が少年と彼の友人たちと遊んでいます。まだ怖くないです。 ハロウィーンは数時間先です。
((再設計されたJMPユーザーコミュニティが登場します!パート2とパート3であなたを見つけることができます! )。
ビデオとコード
このビデオシーケンスは、球の周りに3200ポイントを均等に配置するためのシミュレーテッドアニーリングを示しています。最初に、ポイントは北極から南極に向かって二重らせん状に配置されます。私はダブルスパイラルを試みていませんでした。もう少し初期の広がりを望んでいましたが、とにかくうまくいきます。色は視覚化のためだけのものです。初期点の後、アニーリングプロセスが始まります。https://en.wikipedia.org/wiki/Annealing_(metallurgy)は、金属を加熱して結晶化した構造を緩和し、原子を異なる関係に移動させる物理的アニーリングプロセスについて説明しています。一部の材料は、10月の太陽の暖かさの中で焼きなましされることさえあります。ここでのJSLはビデオ用に調整されており、他の目的には最適化されていません...しかし十分に優れています。アニーリングフェーズ中、加熱と冷却のスケジュールにより、ポイントが最も近い隣接ポイントからどれだけ離れることができるかが制御されます。ポールにはたくさんのポイントが密集しているため、それらのポイントが移動する時間を確保するために、スケジュールはシステムを少し熱く保つ必要があります。その「高温」では、ポイントは十分にジャンプしているため、別のポイントの近隣に行き過ぎてしまうことがよくあります。スケジュールの段階的な冷却フェーズでは、ポイントが落ち着き、移動が少なくなります。彼らが完全に落ち着く前に、ビデオは終了します。
https://www.youtube.com/watch?v=8-Fjw1wD-Oc

nnodes = 3200;
xx = -nnodes * 3/2;
nodelocs = J(nnodes、3、0); //各ノードのx、y、zポイント
For(i = 1、i <= nnodes、i ++、
f = i / nnodes; // 0..1
z = Cos(f * Pi()); // 上から下へ
r = Sin(f * Pi()); //半径
x = Sin(10000 * f)* r; //10,000ラジアン
y = Cos(10000 * f)* r; //多すぎます。しかし、それは機能します...
nodelocs [i、1] = x;
nodelocs [i、2] = y;
nodelocs [i、3] = z;
);
// nodeobj =シーンdisplaylist(); nodeobj << sphere(.1,7,7);
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];
// show(pos、delta);
結果<
rgb = Color To RGB(Heat Color(inode / nnodes、 "spectral"))* 1;
// show(inode / nnodes、rgb);
結果<
結果<
;
);
結果<
結果//ディスプレイリストを返す
;
);
// a = addnodes();
//ノードを半径1の球に約0,0,0アニメーション化します
Adjust = Function({d}、
{inode、radius、closest、dist、err、pos、newlocs = J(nnodes、3、。)、table = KDTable(nodelocs)}、
For(inode = 1、inode <= nnodes、inode ++、
pos = nodelocs [inode、0];
//最近傍から少し離れる
テーブル<
{最も近い、dist}=テーブル<
テーブル<
For(iclose = 1、iclose <= 5、iclose ++、
err = pos --nodelocs [closest [iclose]、0] + J(1、3、Random Normal(0、.01)); // [dx dy dz]
// pos = pos + .00991 / err; // 立ち去る
For(idim = 1、idim <= 3、idim ++、
If(err [idim] <0、
pos [idim]-= d / iclose、
pos [idim] + = d / iclose
)。
);
);
//半径を1.000に近づけます
radius = Sqrt(Sum(pos:* pos));
// err=1.0-半径; //半径が小さすぎる場合、エラーは正です
pos = pos / radius; //大きなエラーはより速く移動します
newlocs [inode、0] = pos; //一時的なコピー
);
nodelocs = newlocs; //tempを実際にコピーします
0//ダミーの戻り値
;
);
角度=30;
シーン=シーンボックス(1924 / 2、1084 / 2);
build = Function({thisnnodes}、
{}、
シーン<<クリア;
シーン<
シーン<
シーン<
シーン<
角度+=.1;
シーン<
シーン<
シーン<
object = addnodes(thisnnodes);
シーン<
);
build(1);
新しいウィンドウ( "ドットワールド"、シーン);
For(i = 1、i <= 3200、i + = 4、
build(i);
シーン<<更新;
Wait(0);
//シーン<
);
For(i = 1、i <5000、i ++、//1000で行われる以外はすべて
vint = Interpolate(i、1、.00001、100、.0005、200、.001、4000、.0005、5000、.00001);
Show(i、vint);
build(3200);
シーン<<更新;
Wait(0);
Adjust(vint);
//シーン<
);
建てる();
シーン<<更新;
Wait(0);
魅力的な視覚化。シミュレーテッドアニーリングのアルゴリズムの実装は、長い間私の個人的な「やること」リストに載っていました。共有していただきありがとうございます。