一連のボロニオ中心 (つまり、それぞれの中心の座標のリスト) が与えられると、各中心に最も近い領域を計算できます。
area[i] = areaClosestTo(i,positions)
中心が正しい場所にないため、これらが少し間違っていると仮定します。したがって、領域を理想的な領域と比較することで、現在のセットの誤差を計算できます。
var areaIndexSq = 0;
var desiredAreasMagSq = 0;
for(var i = 0; i < areas.length; ++i) {
var contrib = (areas[i] - desiredAreas[i]);
areaIndexSq += contrib*contrib;
desiredAreasMagSq += desiredAreas[i]*desiredAreas[i];
}
var areaIndex = Math.sqrt(areaIndexSq/desiredAreasMagSq);
これは、領域と desiredAreas の間の差分ベクトルのベクトル ノルムです。最小二乗適合線がどれだけ優れているかの尺度のように考えてください。
ある種のハニカム パターンも必要なので、それを と呼びhoneycombness(positions)
、物の品質の全体的な尺度を取得できます (これは単なるスターターであり、これの重み付けまたは形式はボートに浮かぶものであれば何でもかまいません)。
var overallMeasure = areaIndex + honeycombnessIndex;
次に、推測がどれほど悪いかを知るメカニズムがあり、これを位置を変更するメカニズムと組み合わせることができます。最も簡単なのは、各中心の x 座標と y 座標にランダムな量を追加することです。または、エリアが高すぎる隣接エリアに向かって各ポイントを移動し、エリアが低すぎるエリアから遠ざけることもできます。
これは単純な解法ではありませんが、各点に最も近い面積を計算する以外に必要な数学は最小限であり、親しみやすいものです。難しい部分は、極小値を認識して対処することかもしれません。
ちなみに、プロセスの開始点を取得するのはかなり簡単なはずです。パイのスライスの重心は、真実からかけ離れていてはなりません。
明確な利点は、中間計算を使用して、パイからボロノイへの遷移をアニメーション化できることです。