うしブログ

うしブログ

趣味で運営する、GeoGebraの専門ブログ。

(作業メモ)StartPoint要検証(2行の場合;テキスト変更時未定義問題)

(要修復)ToggleButton・RollPolygonWithoutSlipping・貯金時計・直感力トレーニング

画面上に大量の点をランダムに生成する

設例

指定した個数の点オブジェクトを、画面上のランダムな位置に生成できるボタンを作りたい。ただし、最も近い点との距離が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を守っては、これ以上点を作成できない、というような場合に、無限ループに陥るのを回避する趣旨である。

 

f:id:usiblog:20190504021637p:plain

 

なお、生成される点の通し番号に、_{}をつけない場合(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);
}