2011-08-16 2 views
3

Scala Javaコードに適合することを表すbresenham's algorithmの次のコードを持っていました。bresenhamのラインアルゴリズムエラー

ほぼすべての行については
def bresenham(x0: Int, y0: Int, x1: Int, y1: Int) = { 
    import scala.math.abs 

    val dx = abs(x1 - x0) 
    val dy = abs(y1 - y0) 

    val sx = if (x0 < x1) 1 else -1 
    val sy = if (y0 < y1) 1 else -1 

    new Iterator[(Int, Int)] { 
     var (x, y) = (x0, y0) 
     var err = dx - dy 

     def next = { 
     val omitted = (x, y) 
     val e2 = 2 * err 
     if (e2 > -dy) { 
      err -= dy 
      x += sx 
     } 
     if (e2 < dx) { 
      err += dx 
      y += sy 
     } 
     omitted 
     } 

     def hasNext = (x <= x1 && y <= y1) 
    } 
    } 

すべてがうまく行くが、私は上から下に垂直線を計算しようとしている(すなわち(0,3) - >(0,0))私は取得しています何もない。
問題はそれほど難しくないので、と言っているhasNextにあるので、私は自分自身について馬鹿だと感じる。上記の場合は)。
私はポイントを交換することでそれを処理しましたが、それは明らかに悪い解決策です。 アルゴリズムの一般化に誰か助けてくれますか?

+0

言ってみ||の代わりに &&。 –

+0

残念ながら、あなたのアプローチは 'ThrowableException:Java heap space'につながります(' hasNext'はほとんどが 'true'になり、実際には行かなくてはならず、行は無限になります)。 –

+0

ちなみに、私はこのコードに同じバグの別のバグを見つけました(例えば(0,0) - >(0,0))無限ループを返します –

答えて

4

エラーの場合は、y0 = 3からy1 = 0に移動しようとしています。したがって、ステップは負の値になります。sy = -1hasNextで続行する条件は、書き込んだ内容(y <= y1)ではなく、y >= y1に依存する必要があります。

hasNextはどちらの方向にも対応できるように一般化する必要があります。賢い方法は、sxsyがゼロでないので動作し、その符号はステップの方向を決定

def hasNext = (sx*x <= sx*x1 && sy*y <= sy*y1) 

だろう。ウィキペディアコードの

+0

ありがとう! @jeelaの答えは、最もきれいで簡単です(乗算は重いですが)私は最後のものを除いてすべての点を得ています。あなたの答えは、正しいものであり、罰金です。 –

2

むしろ逐語訳は次のようになります。

def hasNext = (!(x==x1 && y==y1)) 
関連する問題