Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Baum zeichnen (https://www.delphipraxis.net/3940-baum-zeichnen.html)

Dr.Silver 7. Apr 2003 10:31


Baum zeichnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Leutz,

Ich probiere einen Baum aus Dreiecken und Vierecken zu zeichnen aber ich bekomme es nicht ganz hin die Linke Seite des Baumes baut sich ja schon perfekt auf aber die rechte Seite baut sich nicht richtig auf. Am ende sollen wenn man am ersten Vierekc anfängt zu zählen der weg bis zum letzten Viereck immer gleich lang sein!! Um es richtig zu verstehn schaut euch mal den Quelltext an.


Hauptunit

Code:
unit MBaum01;

interface

uses
  UConfig,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Math;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Paint: TButton;
    procedure FormCreate(Sender: TObject);
  private
    Auswahl: Integer;
    zaehler: Integer;
    OldAlpha: Double;
    Ast,i,j,row: Integer;
    a,b,c,c1, alpha, beta, gamma: Double;
    procedure PaintTree_Dreieck(XPoint1,YPoint1,XPoint2,YPoint2: Integer);
    procedure PaintTree_Viereck(XPoint1,YPoint1,XPoint2,YPoint2: Integer);
    procedure PaintTree_NewViereck(XPoint1,YPoint1,XPoint2,YPoint2: Integer);
  public
    SeitenLaenge: array [1..QUADRATE] of array [0..5] of Double;
    Old_alpha  : array [1..QUADRATE] of array [0..5] of Double;
    X_Point1    : array [1..QUADRATE] of array [0..5] of Integer;
    Y_Point1    : array [1..QUADRATE] of array [0..5] of Integer;
    X_Point2    : array [1..QUADRATE] of array [0..5] of Integer;
    Y_Point2    : array [1..QUADRATE] of array [0..5] of Integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
//  ShowMessage(FloatToStr(power(2,12)));
  Image1.Width := IMGWIDTH;
  Image1.Height := IMGHEIGHT;
  Form1.Width := IMGWIDTH + 10;
  Form1.Height := IMGHEIGHT + 60;
  Paint.Top := IMGHEIGHT + 4;
  Paint.Left := 0;
  Image1.Canvas.Rectangle(IMGWIDTH div 2 - VIERECK div 2, IMGHEIGHT - VIERECK,
                          IMGWIDTH div 2 + VIERECK div 2, IMGHEIGHT);
  c := VIERECK;
  i := 0;
  j := 1;
  row := 0;
  Auswahl := 1;
  zaehler := 0;
  Ast := Tiefe;
  PaintTree_Dreieck(IMGWIDTH div 2 - VIERECK div 2,IMGHEIGHT - VIERECK,
                    IMGWIDTH div 2 + VIERECK div 2,IMGHEIGHT - VIERECK);
end;

procedure TForm1.PaintTree_Dreieck(XPoint1,YPoint1,XPoint2,YPoint2: Integer);
var
  YHilfsPoint, XHilfsPoint: Integer;
begin
  gamma := 90;
  a := c/1.41;
  b := sqrt((c*c) - (a*a));
  c1 := b;
  alpha := arcsin(a * sin(gamma/180*PI) / c) * (180/PI);
  OldAlpha := OldAlpha + alpha;
  c := b;
  // Dreieckberechnung
  gamma := 90;
  alpha := 90 - OldAlpha;
  beta := 180 - gamma - alpha;
  XHilfsPoint := Round(XPoint1+(c * sin(alpha/180*PI) / sin(gamma/180*PI)));
  YHilfsPoint := Round(YPoint1-(c * sin(beta/180*PI) / sin(gamma/180*PI)));
  zaehler := zaehler + 1;
  // Berechnung für den OberenPunkt (Punkt C)
  if zaehler <= Ast then begin                                          // ersterdruchschlauf
    Image1.Canvas.Polygon([Point(XPoint1,YPoint1),Point(XPoint2,YPoint2),
                          Point(XHilfsPoint,YHilfsPoint)]);
    PaintTree_NewViereck(XHilfsPoint,YHilfsPoint,XPoint2,YPoint2); // Viereck Rechteseite Dreieck
    PaintTree_Viereck(XPoint1,YPoint1,XHilfsPoint,YHilfsPoint);    // Viereck Linkeseite Dreieck
  end else if ast <> 1 then begin                                 // aufbau das Bames Linkes Viereck
    i := i + 1;
    Ast := Ast - 1;
    zaehler := ast-i;
    Oldalpha := Old_alpha[Tiefe-i,0] - 90;
    c := SeitenLaenge[Tiefe-i,0];
    // neue Werte fürs Dreieck zugewiesen
    PaintTree_Dreieck(X_Point1[Tiefe-i,0],Y_Point1[Tiefe-i,0],X_Point2[Tiefe-i,0],Y_Point2[Tiefe-i,0]); // Dreieck zeichnen
  end
  else begin
  //---->anfang-test<---
//  ast := Tiefe;
//  PaintTree_Dreieck(X_Point1[row,0],Y_Point1[row,0],X_Point2[row,0],Y_Point2[row,0]);
  Image1.Canvas.Pen.Color := clRed;
  Image1.Canvas.MoveTo(X_Point1[row-4,0],Y_Point1[row-4,0]);
  Image1.Canvas.LineTo(X_Point2[row-4,0],Y_Point2[row-4,0]);
  Image1.Canvas.Pen.Color := clBlack;
  //----->Yende-test<----
  end;
end;

procedure TForm1.PaintTree_Viereck(XPoint1,YPoint1,XPoint2,YPoint2: Integer);
var
  XHPoint1, YHPoint1: Integer;
  YHilfsPoint, XHilfsPoint: Integer;
begin
  XHPoint1 := XPoint1;
  YHPoint1 := YPoint1;
  alpha := 90;
  beta := 180 - 90 - oldalpha;
  gamma := 180 - alpha - beta;
  XPoint1 := Round(XPoint1-(c * sin(gamma/180*PI) / sin(alpha/180*PI)));
  YPoint1 := Round(YPoint1-(c * sin(beta/180*PI) / sin(alpha/180*PI)));
  XHilfsPoint := Round(XPoint1+(c * sin(beta/180*PI) / sin(alpha/180*PI)));
  YHilfsPoint := Round(YPoint1-(c * sin(gamma/180*PI) / sin(alpha/180*PI)));
  Image1.Canvas.Polygon([Point(XHPoint1,YHPoint1),Point(XPoint1,YPoint1),
                        Point(XHilfsPoint,YHilfsPoint),Point(XPoint2,YPoint2)]); // Viereckzeichnen
  PaintTree_Dreieck(XPoint1,YPoint1,XHilfsPoint,YHilfsPoint); //Dreieck aufrufen
end;

procedure TForm1.PaintTree_NewViereck(XPoint1,YPoint1,XPoint2,YPoint2: Integer);
var
  XHPoint2, YHPoint2: Integer;
  XHPoint1, YHPoint1: Integer;
begin
  alpha := 90;
  beta := 180 - 90 - oldalpha;
  gamma := 180 - alpha - beta;
  XHPoint2 := XPoint2;
  YHPoint2 := YPoint2;
  XHPoint1 := XPoint1;
  YHPoint1 := YPoint1;
  XPoint2 := Round(XHPoint2+(a * sin(beta/180*PI) / sin(alpha/180*PI)));
  YPoint2 := Round(YHPoint2-(a * sin(gamma/180*PI) / sin(alpha/180*PI)));
  XPoint1 := Round(XPoint2-(a * sin(gamma/180*PI) / sin(alpha/180*PI)));
  YPoint1 := Round(YPoint2-(a * sin(beta/180*PI) / sin(alpha/180*PI)));
  Image1.Canvas.Polygon([Point(XHPoint1,YHPoint1),Point(XPoint1,YPoint1),
                        Point(XPoint2,YPoint2),Point(XHPoint2,YHPoint2)]); //Viereckzeichnen
  row := row +1;
  SeitenLaenge[row,0]:= a;
  Old_alpha[row,0]  := Oldalpha;
  X_Point1[row,0]   := XPoint1;
  Y_Point1[row,0]   := YPoint1;
  X_Point2[row,0]   := XPoint2;
  Y_Point2[row,0]   := YPoint2;
  //Werte speichern
end;

end.
config unit

Code:
unit UConfig;

interface

const
  TIEFE    = 6;   // Anzahl der Dreiekce
  QUADRATE = 64;  // Anzahl der Vierecke
  { immer die Zahl 2^Tiefe (2 hoch Tiefe) eingeben
  0  =    1  |  1  =    2  |  2  =    4  |  3  =    8  |  4  =   16  |  5  =   32
  6  =   64  |  7  =  128  |  8  =  256  |  9  =  512  |  10 = 1024  |  11 = 2048
  12 = 4096  |  13 = 8192  |  14 = 16384  |  15 = 32768  |  16 = 65536  |  17 = 31072 }
  VIERECK  = 100; //Größe erstes Viereck
  IMGWIDTH = 800;
  IMGHEIGHT = 600;

implementation


end.

schonmal thx
der Doc

P.S. wenn ihr euch den Ahnhang runter ladet wisst ihr wie es aussehen soll!!!

Mario 8. Apr 2003 08:38

Ich habe mir die Routinenen mal angeschaut:

Zitat:

die Linke Seite des Baumes baut sich ja schon perfekt auf aber die rechte Seite baut sich nicht richtig auf
Die linke Seite baute sich auch nur links-lastig auf. Perfekt ist das nicht :?

Ich würde Dir raten, noch mal anzufangen und es mal mit einer richtigen Rekursion zu versuchen. Ich sehe, dass Du es versucht hast, aber so gesehen brauchst Du bei einer Rekursion kein Array, wo Du die Koordinaten zwischenspeicherst.

Ich würde mir das mal aufmalen und mit polaren Koordinaten angehen. Dann sollte es sich recht einfach lösen lassen.

Du brauchst nur eine Routine: Zeichne_Quadrate_ueber_Basislinie. Und diese zeichnet die beiden Quadrate und ruft sich wieder dabei zwei mal auf, mit der neuen Basislinie. Das Dreieck zeichnen kann ganz entfallen, dies ergibt sich ja aus den einschliessenden Quadraten.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:52 Uhr.

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