2011-01-12 14 views
24

2点間の線の座標を計算するための高速アルゴリズムが必要です。私は良いJavaScript Bresenhamの実装を見つけようとしましたが、あまりにも多くの非常に混乱している出版物があります。ウィキペディアで - here最速かつ最も単純な形式(無部門と両方向のためのエラー計算)このように擬似コードで提供されて:あなたは、この擬似コードに基づいたシンプルかつ堅牢なJavaScriptのブレゼンハムの実装のBresenhamアルゴリズムin Javascript

function line(x0, y0, x1, y1) 
    dx := abs(x1-x0) 
    dy := abs(y1-y0) 
    if x0 < x1 then sx := 1 else sx := -1 
    if y0 < y1 then sy := 1 else sy := -1 
    err := dx-dy 

    loop 
    setPixel(x0,y0) 
    if x0 = x1 and y0 = y1 exit loop 
    e2 := 2*err 
    if e2 > -dy then 
     err := err - dy 
     x0 := x0 + sx 
    if e2 < dx then 
     err := err + dx 
     y0 := y0 + sy 
    end loop 

知っていますか?

EDIT

おかげでみんな!これは私が最後に付属のものです:

はJavaScriptにあなたの供給の擬似コードを書き換え
function calcStraightLine (startCoordinates, endCoordinates) { 
    var coordinatesArray = new Array(); 
    // Translate coordinates 
    var x1 = startCoordinates.left; 
    var y1 = startCoordinates.top; 
    var x2 = endCoordinates.left; 
    var y2 = endCoordinates.top; 
    // Define differences and error check 
    var dx = Math.abs(x2 - x1); 
    var dy = Math.abs(y2 - y1); 
    var sx = (x1 < x2) ? 1 : -1; 
    var sy = (y1 < y2) ? 1 : -1; 
    var err = dx - dy; 
    // Set first coordinates 
    coordinatesArray.push(new Coordinates(y1, x1)); 
    // Main loop 
    while (!((x1 == x2) && (y1 == y2))) { 
     var e2 = err << 1; 
     if (e2 > -dy) { 
     err -= dy; 
     x1 += sx; 
     } 
     if (e2 < dx) { 
     err += dx; 
     y1 += sy; 
     } 
     // Set coordinates 
     coordinatesArray.push(new Coordinates(y1, x1)); 
    } 
    // Return the result 
    return coordinatesArray; 
    } 

答えて

42

:あなたは(それがときいけないのにステップとして直接山車を比較すると、失敗する可能性があること

function line(x0, y0, x1, y1){ 
    var dx = Math.abs(x1-x0); 
    var dy = Math.abs(y1-y0); 
    var sx = (x0 < x1) ? 1 : -1; 
    var sy = (y0 < y1) ? 1 : -1; 
    var err = dx-dy; 

    while(true){ 
    setPixel(x0,y0); // Do what you need to for this 

    if ((x0==x1) && (y0==y1)) break; 
    var e2 = 2*err; 
    if (e2 >-dy){ err -= dy; x0 += sx; } 
    if (e2 < dx){ err += dx; y0 += sy; } 
    } 
} 

注意整数量によってステッピング、それはどちらかのエンドポイント)が非整数である可能性がある場合、その代わりに、直接エンドポイントを比較するあなたはイプシロンを使用する場合があります:

if (Math.abs(x0-x1)<0.0001 && Math.abs(y0-y1)<0.0001) break; 

これは必ずしもあなたが遅くなりますただし、非整数を扱う場合にのみこれを行うようにしてください。

+2

ブラッセンハムは整数だけで動作するはずです。ラインを描画するためにどのピクセルを色付けするかを計算するために使用されます。 –

+1

私はこれを気に入っていますが、実際のループ条件に合わせてブレークを削除し、シフトで2倍の乗算を行うことで、さらに改善できると思います。 –

+2

ビットシフトは頭髪の方が速いかもしれませんが、ループの変更がパフォーマンスに影響することは疑いの余地があります。あなたは 'while(x0!= x1 || y0!= y1)'に簡単に変更して 'if/break'を削除することができますが、処理するループの前/後に' setPixel'をもう一度呼び出す必要があります線の端点と端点の場合です。 – Phrogz