2017-11-04 13 views
2

Ich habe versucht, Bresenham Linie Algorithmus aus der Wikipedia Page zu implementieren, und ich habe ein seltsames Problem, das zu einer Ausnahme führt aufgetreten.Index war außerhalb der Grenzen des Arrays Doppel C# (Doppel)

public static int[,] Line(int x0, int y0, int x1, int y1) 
    { 
     int arraySizeX = x1 - x0; 
     int arraySizeY = y1 - y0; 
     int [,] outputArray = new int[arraySizeX, arraySizeY]; 
     //Bresenham's line algorithm from Wikipedia 
     double deltax = x1 - x0; 
     double deltay = y1 - y0; 

     double deltaerr = Math.Abs(deltay/deltax); // Assume deltax != 0 (line is not vertical), 
     double error; 
     error = 0.0;//no error at start 
     int y = 0; 

     for(int x = x0; x1 >= x; x++) 
     { 
      outputArray[x, y] = 1; 
      error += deltaerr; 
      while(error >= 0.5) 
      { 
       y = y + Math.Sign(deltay) * 1; 
       error = error - 1.0; 
      } 
     } 

     return outputArray; 
    } 

Und wenn ich es testen mit:

Line(2, 1, 5, 3); 

es die Ausnahme zurück:

System.IndexOutOfRangeException: 'Index außerhalb der Grenzen des Arrays war'

an dieser Linie:

   error += deltaerr; 

Dies geschieht auf der zweiten Iteration der for-Schleife. An diesem Punkt die beiden Werte sind:

error -0.33333333333333337 double 

und

deltaerr 0.66666666666666663 double 

In meinem Kopf Fehler sollte so etwas wie 0.3333 zugeordnet werden. Irgendwelche Hinweise darauf, was schief gelaufen sein könnte?

Dies ist meine erste Frage, also bitte sagen Sie mir, wie ich mich in Zukunft verbessern könnte. Vielen Dank.

Lösung: Achten Sie genau auf alle Arrays im Code.

Der Fehler war tatsächlich auf der Linie über wo der Code versucht, eine Position im Array zu verweisen, die nicht existierte.

+1

gegebene Eingabe: 'Leitung (2, 1, 5, 3);' das mehrdimensionale Array im wesentlichen als 'int definiert [,] output = new int [3, 2];' Sie können sich das als eine Tabelle von 3 Zeilen und 2 Spalten vorstellen. Das Problem ist jedoch, dass die for-Schleife-Iterationsvariable "x" über die Anzahl der verfügbaren Zeilen hinausgeht. Sie können dies leicht mit einem Debugger lösen und sicherstellen, dass Ihr Algorithmus korrekt ist. –

+0

Der Fehler 'IndexOutOfRangeException' kann nicht in dieser Zeile 'error + = deltaerr;' auftreten, da diese Zeile keine Indizierung beinhaltet. Dies muss 'outputArray [x, y] = 1; ', wobei das Array mit' [x, y] 'indiziert wird. Ich erkläre es ausführlich in meiner Antwort. –

Antwort

1

Die Ausnahme tritt in der Zeile oben auf, wenn Sie versuchen, auf das Array zuzugreifen.

outputArray[x, y] = 1; 

Wenn Sie Ihre Methode aufrufen Line(2, 1, 5, 3); Sie ein Array von der Größe schaffen new int[3,2]

int arraySizeX = x1 - x0; // 5 - 2 = 3 
int arraySizeY = y1 - y0; // 3 - 1 = 2 
int [,] outputArray = new int[arraySizeX, arraySizeY]; // new int[3,2] 

So jetzt Ihre for Schleife x0 = 2-x1=5 laufen, so dass Sie aus dem Rennen Array-Bereich. Darum geht es in Ihrer Ausnahme.


Um dies zu beheben, sollten Sie von x < x1-x0 von x = 0 und beenden Sie Ihre for Schleife durch x = 0 und Ende von x <= x1-x0-1 oder starten starten.

1

Wenn Sie ein Array mit

new int[arraySizeX, arraySizeY] 

dann die Indexbereiche erstellen sind

[0 .. arraySizeX - 1, 0 .. arraySizeY - 1] 

Sie müssen nie diese Grenzen überschreiten. Subtrahieren x0 oder y0 aus den Koordinaten Indizes zu erhalten, die

for (int x = x0; x1 >= x; x++) 
{ 
    outputArray[x - x0, y - y0] = 1; 
    ... 
} 

Ein weiteres Problem ist innerhalb dieser Grenzen sind, dass Sie bis x == x1 sind Looping. Daher sollte die Array-Größe int arraySizeX = x1 - x0 + 1 sein. Das Gleiche gilt für arraySizeY (denn wenn y0 == y1, d. H. Die Zeile horizontal ist, muss die Array-Größe 1 sein, nicht 0).

(vorausgesetzt, Sie auch, dass x1 > x0 und y1 >= y0, sonst könnte man negative Feldgrößen erhalten)


Aber ein realistischer Ansatz wäre „ziehen“ die Pixel in ein Array, das die Bildgröße, anstatt nur das widerspiegelt Liniengröße und die Endpunkte der Linie müssten innerhalb des Bildes liegen. Eine zusätzliche Logik würde Linien schneiden, die die Bildgrenzen kreuzen. Siehe: Cohen–Sutherland algorithm für Line clipping.

int[,] image = new int[imageWidth, imageHeight]; 

Mit x0 und x1 im Bereich [0 .. imageWidth-1] und y0 und y1 im Bereich [0 .. imageHeight-1].

Verwandte Themen