Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Endlosschleife (https://www.delphipraxis.net/97221-endlosschleife.html)

daschaos 7. Aug 2007 11:37


Endlosschleife
 
Hi!

Ich möchte einen Squarified Treemap - Algorithmus implementieren. Auf meinen kleinen Testdaten hatte alles wunderbar funktioniert, jetzt hab ich mir aber reale Daten von der Festplatte geholt und mein Programm stürzt ab. Nach langem Suchen ist mir aufgefallen, dass irgendwie eine Endlosschleife produziert wird. Und zwar ist ja ein continue im if-Teil von LastAspect>CurrentAspect, das heißt, immer wenn er in den If - Teil reingeht, springt er beim continue aus der Schleife raus und beginnt mit einem neuen Durchlauf. EndIndex, welcher ja bei EndIndex=ChildCount zum Abbruch der Schleife führt, wird aber nur im Else - Teil von LastAspect>CurrentAspect erhöht. Wenn ich jetzt das Continue mal ausklammer, malt er es nich mehr hundertprozentig richtig, er malt das letzte Kind der jeweiligen Verzeichnisebene glaub ich nich mehr, ansonsten stürzt das Programm aber nicht mehr ab, weil EndIndex in jedem Fall erhöht wird. Also liegt es daran, dass EndIndex nich immer erhöht wird und somit manchmal zu einer Endlosschleife führt. Ich bin irgendwie wie so oft anscheinend zu blöd dafür, das Problem behoben zu bekommen, ohne diesen Continue Sprung zu benutzen.

Der Code, in dem der Fehler auftritt:


Delphi-Quellcode:
while (EndIndex <> ChildCount) do
  begin
    // compute aspect ratio with current start- and end index
    LastAspect := SquarifiedTryLayout(StartIndex, EndIndex, Orientation, TempWidth, TempHeight);

    // if the computed aspect ratio is greater than CurrentAspect
    if ((LastAspect > CurrentAspect) or (LastAspect < 1)) then
    begin
      CurrentX := ARect.TopLeft.X;
      CurrentY := ARect.TopLeft.Y;

      // the new calculated aspect is inferior, so codify the calculated coordinates for the starting point of a rectangle
      for i:= StartIndex to EndIndex-1 do
      begin
        SortArray[i].X := OffsetX + CurrentX;
        SortArray[i].Y := OffsetY + CurrentY;

        // set new starting points
        if (Orientation)then
          CurrentY := Single(CurrentY) + Single(SortArray[i].Height)
        else
          CurrentX := Single(CurrentX) + Single(SortArray[i].Width);
      end;//for

      if (Orientation) then
        OffsetX := Single(OffsetX) + Single(SortArray[StartIndex].Width)
      else
        OffsetY := Single(OffsetY) + Single(SortArray[StartIndex].Height);

      // calculate the leftover size of the width and height of the rectangle
      TempWidth := AWidth - OffsetX;
      TempHeight := AHeight - OffsetY;

      // check, if orientation has changed and you have to draw vertical or horizontal now
      Orientation := DrawingOrientation(TempWidth, TempHeight);
      StartIndex := EndIndex;
      CurrentAspect := 999;
      continue;
    end//if(LastAspect>CurrentAspect)
    else
    begin
      // store the temp measurements
      for i:= StartIndex to EndIndex do
      begin
        SortArray[i].Width := SortArray[i].TempWidth;
        SortArray[i].Height := SortArray[i].TempHeight;
      end;//for

      // store the last aspect for later comparisons
      CurrentAspect := LastAspect;

      end;//else

      // increment index to try to draw another rectangle
      EndIndex := EndIndex + 1;
  end;//while(EndIndex <> ChildCount)
Es wäre ganz ganz toll, wenn jemand eine Idee hätte, wie ich mein Problem lösen könnte! Ich wäre euch auf Lebenszeit dankbar!

Der_Unwissende 7. Aug 2007 12:44

Re: Endlosschleife
 
Hi,

also dass der EndIndex nur im else-Fall verändert wird kannst Du auch natürlich auch erreichen, indem Du einfach seine Inkrementierung in den else Teil nimmst und das Continue weglässt. Das der Code an der Stelle anders arbeitet lässt aber darauf schließen, dass das nicht der Sinn des Algorithmus ist. Die Frage ist hier also schon, wie kommst Du auf den Algorithmus da unten?
Da ich den Squarified Treemap Algorithmus nicht kenne, kann ich im Moment aber auch nur wenig dazu sagen. An sich denke ich ist das Continue definitiv falsch. Wird nur eine bestimmte Ebene weggelassen ohne Continue, so hast Du wahrscheinlich einen Indexierungsfehler. Hier solltest Du Dir überlegen, ob Du irgendwo eine Indexverschiebung (1 statt 0 indiziert) verwendest und somit auch die while-Schleife erst bei ChildCount + 1 abbrechen sollte (o.Ä.).

Gruß Der Unwissende


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz