Autor Beitrag
jawo3
Hält's aus hier
Beiträge: 10



BeitragVerfasst: So 13.02.11 00:12 
Hallo,
ich habe vor kurzem einen Quelltext zur grafischen Darstellung eines Binärbaumes (mit Buchstaben von A-Z) erhalten und diesen jetzt implementiert. Allerdings ist mir aufgefallen, dass die Umsetzung nicht sonderlich gut ist.

Wenn ich zum Beispiel die Buchstaben: (P,A,B,C,D,Z,Y,X,W,V) in dieser Reihenfolge eingebe gibt es in der Mitte eine Überschneidung (siehe original Screenshot-Ausschnitt im Anhang). Dort fällt außerdem auf, dass die Elemente, die zur linken Seite eingeordnet werden sollen, grundsätzlich einen größeren horizontalen Abstand zum übergeordneten Element haben, als solche Elemente, die zur rechten Seite eingeordet werden.

Hier der Quellcode mit den beiden zugehörigen Prozeduren:


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
procedure GrafikAusgabe(a:Zeiger;xx,yy,ii,rr:integer); //Prozedur zur Ausgabe der Grafik
var ll,oo:integer;
begin
  if a<>nil then
  begin
    GrafikAusgabe(a^.links,xx-(100 div ii)-5,yy+40,ii+1,1);
    Form1.ImageZeichnung.Canvas.TextOut(xx,yy,a^.Inhalt);
    if ii>1 then
    begin
      ll:=xx+length(a^.Inhalt)*5-(length(a^.Inhalt)*5div 2;
      oo:=yy-1;
      Form1.ImageZeichnung.Canvas.MoveTo(ll,oo);
      ll:=ll+((100 div (ii-1))+5*rr)*rr;
      oo:=oo-25;
      Form1.ImageZeichnung.Canvas.LineTo(ll,oo);
    end;
    GrafikAusgabe(a^.rechts,xx+(100 div ii)-5,yy+40,ii+1,-1);
  end;
end;


procedure GrafikSteuerung();
var rect: TRect;
     xkoord, ykoord: integer;
begin
  xkoord:=Form1.ImageZeichnung.Width div 2;
  ykoord:=10;
  rect:=Bounds(0,0,Form1.ImageZeichnung.Width,Form1.ImageZeichnung.Height);
  Form1.ImageZeichnung.Canvas.Brush.Color:=clwhite;
  Form1.ImageZeichnung.Canvas.FillRect(rect);
  GrafikAusgabe(wurzel,xkoord,ykoord,1,1);
end;

Ich habe heute den ganzen Tag versucht, dass irgendwie umzuschreiben, sodass diese Probleme nicht auftreten, meine größte Schwierigkeit dabei ist allerdings, dass ich dem Quelltext-Abschnitt selbst nicht so ganz folgen kann. Ich habe ein paar Änderungen gemacht, was dazu geführt, dass Elemente plötzlich außerhalb des Images eigeordnet wurden, weil anscheinend der Bezugspunkt nicht richtig war. Hier mal mein Versuch (bisher noch ohne Verbindungsstriche). Eine falsche Darstellung tritt zum Beispiel bei Eingabe von "C,A,B" auf (das B wird rechts neben das C geschrieben in dem Abstand in dem es eigentlich vom A entfernt sein sollte:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure GrafikAusgabe(a:Zeiger;xx,yy,ii,rr:integer); //Prozedur zur Ausgabe der Grafik
var ll,oo:integer;
begin
  if a<>nil then
  begin
    GrafikAusgabe(a^.links,xx-(xx div 2)-5,yy+40,ii+1,1);
    Form1.ImageZeichnung.Canvas.TextOut(xx,yy,a^.Inhalt);
    GrafikAusgabe(a^.rechts,xx+((Form1.ImageZeichnung.Width-xx) div 2)-5,yy+40,ii+1,-1);
  end;
end;



Ich hoffe ihr könnt mir ein bisschen auf dem Weg zu einer problemfreien Lösung helfen.

Vielen Dank im Voraus
jawo3


Moderiert von user profile iconMartok: Delphi-Tags gesetzt
Moderiert von user profile iconMartok: Topic aus Sonstiges (Delphi) verschoben am So 13.02.2011 um 00:04
Einloggen, um Attachments anzusehen!
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: So 13.02.11 01:09 
Hallo und :welcome: in der EE!

Bitte verwende für Quellcode die entsprechenden [delphi]-Tags, dann wird er "schöner" dargestellt als im Fließtext. Beispiel:
ausblenden Quelltext
1:
<span class="inlineSyntax"><span class="codecomment">{PROTECTTAG93f0e1576102a987b6704409a064690c}</span></span>					

Wird:
ausblenden Delphi-Quelltext
1:
var Test: integer;					


Außerdem möchte ich dich bitten, Grafiken nicht als BMP sondern als komprimierte (PNG, JPG o.ä.) hochzuladen. Viel kleiner und viel schneller angezeigt ;)

Ich habe das mal für dich erledigt, fürs nächste mal dann.

Viele Grüße,
Martok

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: So 13.02.11 02:08 

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: So 13.02.11 10:24 
Vom Konzept her würd ich sagen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure Knoten_Draw( A: TKnoten; Left,Top,Width: real);
begin
  PaintKnotenAt(Left+Width/2,Top);

  if A.Links<>nil then
    Knoten_Draw( A.Links, Left,Top+25,Width/2);
  if A.Rechts<>nil then
    Knoten_Draw( A.Rechts, Left+Width/2,Top+25,Width/2);
end;

procedure StartDraw;
begin
  KnotenDraw( Wurzel, 2525, Image1.Width-50); //25 Platz nach oben, und am Rand
end;


Um den Baum auch in der Höhe dem Image anzupassen muss natürlich erstmal die Höhe des Baumes bekannt sein.

Edit:
user profile iconjawo3 hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden Delphi-Quelltext
1:
 GrafikAusgabe(a^.rechts,xx+((Form1.ImageZeichnung.Width-xx) div 2)-5,yy+40,ii+1,-1)					

Das kann so nicht funktionieren, da du so immer bis zum rechten Rand aus rechnest (auch von dem knoten ganz links aus)

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)

Für diesen Beitrag haben gedankt: jawo3
jawo3 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: So 13.02.11 16:02 
Super, danke für die Hilfe.
Die Anordnung der Elemente funktioniert jetzt zu vollster Zufriedenheit.

Das nächste Problem besteht jetzt allerdings darin, dass die Verbindungslinien entsprechend nicht funktionieren.

Hier der Quellcode:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure GrafikAusgabe(a:Zeiger;left,top,width,ii: integer);   
var ll,oo: integer;
begin
  Form1.ImageZeichnung.Canvas.TextOut(left+width div 2,top,a^.Inhalt);
  if ii>1 then
    begin
      //Form1.ImageZeichnung.Canvas.MoveTo(_______________);
      //Form1.ImageZeichnung.Canvas.LineTo(_______________);
    end;
  if a^.Links<>nil then GrafikAusgabe(a^.links,left,top+50,width div 2,ii+1);
  if a^.Rechts<>nil then GrafikAusgabe(a^.rechts,left+width div 2,top+50,width div 2,ii+1);
end;

procedure GrafikSteuerung();
var  rect: TRect;                
begin
  rect:=Bounds(0,0,Form1.ImageZeichnung.Width,Form1.ImageZeichnung.Height);  
  Form1.ImageZeichnung.Canvas.Brush.Color:=clwhite;                 
  Form1.ImageZeichnung.Canvas.FillRect(rect);                          
  if wurzel<>nil then GrafikAusgabe(wurzel,0,25,Form1.ImageZeichnung.Width-50,1);
end;


Vielleicht könnt ihr mir einen Denkanstoß geben, das wäre klasse.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: So 13.02.11 16:58 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
if a^.links<>nil then
  begin
    Form1.ImageZeichnung.Canvas.MoveTo(left+width div 2,top); //da ist die Wurzel
    Form1.ImageZeichnung.Canvas.LineTo(left+width div 4,top+50); // 1/4 width
  end;

if a^.rechts<>nil then
  begin
    Form1.ImageZeichnung.Canvas.MoveTo(left+width div 2,top); //da ist die Wurzel
    Form1.ImageZeichnung.Canvas.LineTo(left+3*(width div 4),top+50); // 3/4 width
  end;

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)

Für diesen Beitrag haben gedankt: jawo3
jawo3 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: So 13.02.11 17:49 
Wow, vielen Dank.
Das funktioniert einwandfrei - ich musste nur noch ein paar Verschiebungen anpassen, sodass die Linien nicht genau im Buchstaben beginnen.

Thema gelöst :D