2012-03-25 12 views
2

私は配列を持っています:int [] [] lawn = new int [980] [1280];円内のすべてのデカルト点を計算する

ブレードの高さの値を芝生に保存します。

私のシミュレーションでは、芝生を回ってブレードを切断するロボットがあります。

私のロボットは、直径(rDiameter)の円の形をしています。 座標系はDoubleで、私の芝生はIntegerです。

私はロボットが芝生を切断できるように2つの "アルゴリズム"を開発しましたが、私のアルゴリズムの精度は十分ではなく、性能も十分ではないため満足できません。

私の質問は、私がすでに考えているアイデア以外にこれを行う方法はありますか?

また、より良い結果を得るために芝生の実装を変更する必要がありますか?

十分明確でない場合は何でもお気軽にお問い合わせください。ここ

は私の2つのアルゴリズム(kはロボットを表す)、中心位置は、ここで私のロボットの中心(SO円の中心)

approach with square 
    int bottomLeftCornerX = (int) (k.getCenterPosition().getX() - simulParams.getKDiameter()/2); 
    int bottomLeftCornerY = (int) (k.getCenterPosition().getY() - simulParams.getKDiameter()/2); 

    for (int i = bottomLeftCornerX; i < bottomLeftCornerX + simulParams.getKDiameter(); i++) { 
     for (int j = bottomLeftCornerY; j < bottomLeftCornerY + simulParams.getKDiameter(); j++) { 
      ((LawnArea) lawn.getBladeHeight()).cutBladeInArea(j, i); 
     } 
    } 

円のアプローチの1つを返すためのコードであります(基本的には、ウィキペディアの中に存在する循環型式です...):

for (int r = 0; r < simulParams.getKDiameter()/2; r++) { 

     for (double t = 0; t < 2 * Math.PI; t = t + 0.1) { 
      Point2D p = circumference(k.getCenterPosition().getX(), k.getCenterPosition().getY(), t, r); 
      int intX = (int) Math.ceil(p.getX()); 
      int intY = (int) Math.ceil(p.getY()); 
       ((LawnArea) lawn.getBladeHeight()).cutBladeInArea(intY, intX); 
      } 
     } 
    } 
+0

なぜ中点サークルアルゴリズムを使用するのではなく、座標を配列に格納してから、円ごとに行を塗りつぶすのはなぜですか? – harold

答えて

0

k.xをx座標であり、 k.yk.rが半径、y座標です。

for(int y = (int)Math.max(0, Math.ceil(k.y - k.r)); y <= (int)Math.min(980, Math.floor(k.y + k.r)); y++) { 
    doulbe dx = Math.sqrt(k.r * k.r - Math.abs(y-k.y) * Math.abs(y-k.y)); 
    for(int x = Math.max(0, (int)Math.ceil(k.x - dx)); x <= (int)Math.min(1280, Math.floor(k.x + dx)); x++) { 
     cut(x,y); 
    } 
}

つのループがあります。
は最初の1であれば、それは常にだった場合(私は知りませんでしたy座標のためのものであり、円はフィールド上completlyある場合k.y + k.rまでk.y - k.rから始まり、行きますはい、あなたはコーナーに到達できません)ので、画面の上部から下部に移動します。
2番目はx座標です。小と最大のxは、公式(k.x - x)²+(k.y - y)²=k.r²の助けを借りて計算されます。
これであなたのサークル内にポイントが得られます。 doubleからintへの変換のために少し小さいです。

+0

あなたの答えをありがとう、私はあなたのコードを試したとうまく動作しますが、私はコーナーに到達することができないという事実とあなたが何をしていない取得していません。 – Seafire37

+0

ダブルをより高い値に丸めた点でブレードをカットしたい場合は、フォーミュラで可能ですか? – Seafire37

+0

それは本当に問題ではありません。私はあなたのロボットがそれを離れることができるかどうかの芝生に常に完全にあるかどうか確信していませんでした。 – IchBinKeinBaum

1

最初のアプローチ(バウンディングボックスに基づく)は良いスタートです。しかし、今では、境界ボックス内の各点が円内にあるかどうかをチェックする条件を追加するだけで済みます。

ような何か:バウンディングボックスのあなたはそれぞれの行(または列)であることに気づいことで、これを改善することができ

for each (point p inside bounding-box) { 
    if (p inside circle centred at k) { 
     cutBlade(p); 
    } 
} 

、カットする必要があるのブレードセットは、すべての隣接しています。この範囲の終点を計算すると、条件は必要ありません。等

何か:読みやすさのため

for each (x inside bounding-box) { 
    calculate y_first; 
    calculate y_last; 
    for (y = y_first; y < y_last; y++) { 
     cutBlade(x,y); 
    } 
} 
+0

あなたの早い返事をありがとう、私はあなたが提案した2つのものを試してみましょう。 – Seafire37

関連する問題