sierpinskidreieck

Schneemann

Grünschnabel
hallo erstmal zusammen

also ich habe folgendes problem: ich möchte das sierpinski dreieck mit hilfe der rekursion programmieren.S wie ich es versucht habe funktioniert es aber nicht (kompletter rechner schmiert ab), ich weiß aber nicht wo das problem liegt. Wäre nett wenn ihr mir weiterhelfen könntet.
ich werde am besten meinen Quelltext angeben:

Code:
procedure sierpinski (ordnung : Integer; laenge, winkel:Real; a: Integer);
var x,y: real;

begin
x := x+laenge*cos(winkel);
y := y-laenge*sin(winkel);
//Form1.PaintBox1.Canvas.LineTo (Round(x),Round(y));

sierpinski (ordnung-1, laenge / 2, winkel,a);
winkel := winkel + 2 * pi / 3;
sierpinski (ordnung-1, laenge / 2, winkel,a);
winkel := winkel - 2 * pi / 3;
sierpinski (ordnung-1, laenge / 2, winkel,a);
winkel := winkel - 2 * pi / 3;
sierpinski (ordnung-1, laenge / 2, winkel,a);
winkel := winkel + 2 * pi / 3;
sierpinski (ordnung-1, laenge / 2, winkel,a);
Inc(a);
Form1.paintbox1.Canvas.LineTo(Round(x),Round(y));
If a < (StrToInt(Form1.Combobox1.Text)) then
  sierpinski (ordnung, laenge, winkel,a)
  else
  exit;
end;
//end;

procedure TForm1.Button1Click(Sender: TObject);

var ordnung : Integer;
x, y, laenge, winkel : Real;
a: Integer;

begin
x := 100;
y := 380;
a:= 0;
refresh;
laenge :=400;
winkel :=0;
ordnung := (StrToInt(ComboBox1.Text));
PaintBox1.Canvas.MoveTo (Round(x), Round(y));
sierpinski (ordnung, laenge, winkel,a);
end;

Button1 ist der Button auf dessen Befehl hin das dreieck gezeichnet wird
Die Combobox gibt an wieviele Stufen das Dreieck haben soll, bzw. wieoft die Rekursionschleife durchlaufen weden soll.

ich hoffe ihr könnt nir aufgrund meiner Angaben helfen
vielen Dank schonmal
Schneemann
 

Maximka

Erfahrenes Mitglied
Deine Abbruchbedingung fuer die Rekusion nicht an der richtigen Stelle.
Die muesste am Anfang der Funktion geprueft werden.
 

Schneemann

Grünschnabel
danke für die antworten schonmal
also "rechner schmiert ab" heißt es kommt ein bluescreen und ein Neustart ist notwending. Mittlerweile passiert dies aber nicht mehr´, sondern es kommt ein ganz normaler "Stack - Überlauf".
Also meiner Meinung nach muss man pi nicht initialisieren, da es ein normaler rechenoperator (wie + und - auch) ist (korrigiert mich, wenn ich falsch liege).

@ maxima
hab schon versucht, die abbruchbedingung an den Anfang zu setzen, hat jedoch nichts gebracht, ein "Stack- Überlauf " kommt trotzdem. Daraus schließe ich, dass zumindest mit der Abbruchbedingung Irgendetwas nicht in Ordnung sein kann, ich weiß aber nicht wo der fehler liegt.

trotzdem nochmal vielen dank für die Hilfen

Schneemann
 

Maximka

Erfahrenes Mitglied
also mal kurz skizziert:

Code:
// zeichnet ein sierpinski dreieck
// ausgehend von jetzigem Standpunkt auf dem gegeben Canvas aus
procedure sierpinski (canvas: TCanvas;ordnung : Integer; laenge, winkel:Real);
var x,y: real;
begin
    if ordnung=0 then
    begin
        // draw triangle
        x:=canvas.PenPos.X+laenge*cos(winkel);
        y:=canvas.PenPos.Y+laenge*sin(winkel);
        canvas.LineTo(Round(x),Round(y));
        x:=canvas.PenPos.X+laenge*cos(winkel+2*pi/3);
        y:=canvas.PenPos.Y+laenge*sin(winkel+2*pi/3);
        canvas.LineTo(Round(x),Round(y));
        x:=canvas.PenPos.X+laenge*cos(winkel+4*pi/3);
        y:=canvas.PenPos.Y+laenge*sin(winkel+4*pi/3);
        canvas.LineTo(Round(x),Round(y));
    end
    else begin
        laenge:=laenge div 2;
        sierpinski(canvas,ordnung-1,laenge,winkel);
        x:=canvas.PenPos.X+laenge*cos(winkel);
        y:=canvas.PenPos.Y+laenge*sin(winkel);
        canvas.MoveTo(Round(x),Round(y));
        sierpinski(canvas,ordnung-1,laenge,winkel);
        x:=canvas.PenPos.X+laenge*cos(winkel+2*pi/3);
        y:=canvas.PenPos.Y+laenge*sin(winkel+2*pi/3);
        canvas.MoveTo(Round(x),Round(y));
        sierpinski(canvas,ordnung-1,laenge,winkel);
    end;
end;

/// und beim aufruf dann
procedure TForm1.Button1Click(Sender: TObject);
var ordnung : Integer;
x, y, laenge, winkel : Real;
begin
    /// untere linke ecke des dreiecks
    x := 100;
    y := 380;
    refresh;
    laenge :=400;
    winkel :=0;
    ordnung := (StrToInt(ComboBox1.Text));
    PaintBox1.Canvas.MoveTo (Round(x), Round(y));
    sierpinski (PaintBox1.Canvas,ordnung, laenge, winkel);
end;

Note:
ist aus dem Kopf geschrieben, wird also bestimmt ohne Fehler sein ;)
 

Schneemann

Grünschnabel
naja ich bin mir nicht ganz sicher ob mir das weiterhilft...
ich verstehe deine Else... Anweisungen nicht so ganz.

Ordnung gibt ja nur an wie oft die rekusion durchlaufen werden soll, also wieviele Stufen das Sierpinski dreieck hat. Hab mir das ungefähr so vorgestellt:
jedesmal wenn die rekursionsprozedur durchlaufen wird, wird eine variable a eins hochgezählt. In einer ComboBox (o.ähnliches) gibt der benutzer an wieviele Stufen das Dreieck haben soll.
Die if... then....Bedingung vergleicht nach jedem durchlaufen der rekursionsprozedur ob a mittlerweile den Wert der ComboBox erreicht hat. Wenn ja wird die prozedur abgebrochen, wenn nein wierd sie nochmal durchlaufen.
Die If..then...Bedingung ist somit die Abbruchbedingung.

ich hoffe ich konnte mein Problem ausreichend erklären,
trotzdem nochmals danke für die Mühe
Schneemann
 

Maximka

Erfahrenes Mitglied
Die Ordnung sagt an die noch verbleibende Rekursionstiefe an, also kannst du abbrechen wenn diese den Wert 0 erreicht.

Mein Else-Zweig zeichnet die drei inneren Dreiecke die in einem Dreieck der hoehren Ordnung zu finden sind.
 

Neue Beiträge