設例
指定した個数の点オブジェクトを、画面上のランダムな位置に生成できるボタンを作りたい。ただし、最も近い点との距離が0.1を下回るような点ができてはならない。 ボタンのOn Click スクリプトを記述せよ。
解答例
以下の関数を、「グローバルJavaスクリプト」欄に記述する。
function generateRandomPoints(pointNumber, headName, minDistance, margin){
var minX = ggbApplet.getValue('x(Corner[1])') + margin;
var maxX = ggbApplet.getValue('x(Corner[3])') - margin;
var minY = ggbApplet.getValue('y(Corner[1])') + margin;
var maxY = ggbApplet.getValue('y(Corner[3])') - margin;
var k = 0;
var repeat = 0;
do{
k++;
var generateX = Math.random() * (maxX - minX) + minX;
var generateY = Math.random() * (maxY - minY) + minY;
ggbApplet.evalCommand(headName+'_{'+k+'} = ('+generateX+','+generateY+')');
var distance = ggbApplet.getValue('Distance[P_{'+k+'}, ClosestPoint[Sequence[Object[\"P_{\" + (s) + \"}\"], s, 1, '+(k-1)+'], P_{'+k+'}]]');
if(distance < minDistance){
k--;
repeat++;
}
else{
repeat = 0;
}
} while (k < pointNumber && repeat < 10);
}
たとえば、
generateRandomPoints(100, 'P', 0.1, 0.5);
は、P_{1}〜P_{100}の100個の点を作成する。点同士の最短距離は、0.1を下回らないように生成する。また、画面の端から(座標にして)0.5までの領域は、余白として、点を生成しないようにしている。
これをボタンのOn Click スクリプトにすればよい。
※なお、上記関数は、10回連続で生成に失敗した場合は、その時点でループを打ち切る設定にしてある。これは、たとえば、画面が狭すぎて、指定したminDistanceを守っては、これ以上点を作成できない、というような場合に、無限ループに陥るのを回避する趣旨である。
なお、生成される点の通し番号に、_{}をつけない場合(P1, P2, ..., P100)は、以下のスクリプトを利用されたい。
function generateRandomPoints(pointNumber, headName, minDistance, margin) {
var minX = ggbApplet.getValue('x(Corner[1])') + margin;
var maxX = ggbApplet.getValue('x(Corner[3])') - margin;
var minY = ggbApplet.getValue('y(Corner[1])') + margin;
var maxY = ggbApplet.getValue('y(Corner[3])') - margin;
var k = 0;
var repeat = 0;
do {
k++;
var generateX = Math.random() * (maxX - minX) + minX;
var generateY = Math.random() * (maxY - minY) + minY;
ggbApplet.evalCommand(headName + k + ' = (' + generateX + ',' + generateY + ')');
var distance = ggbApplet.getValue('Distance[P' + k + ', ClosestPoint[Sequence[Object[\"P\" + (s) ], s, 1, ' + (k - 1) + '], P' + k + ']]');
if (distance < minDistance) {
k--;
repeat++;
} else {
repeat = 0;
}
} while (k < pointNumber && repeat < 10);
}