![]() |
Geschriebenes Programm stürzt ab
Hallo liebe Forengemeinde,
Ich habe ein Problem, dass ich rein gar nicht verstehe, ich soll für die Schule eine Pyramide zeichnen, in der sich immer kleiner werdende andere Pyramiden schachteln mit Hilfe von Variablen zeichnen. Ich bin leider nicht weit gekommen, denn bei dem Eintrag
Delphi-Quellcode:
In einer while Schleife stürzt das Programm ab, nachdem ich den Button zum Zeichnen gedrückt habe, d.h. es reagiert nicht mehr, zeichnet aber auch nicht. Ich kann es nur über Run-->Program Reset schließen, komischerweise läuft das Programm, wenn ich das geteilt durch 2 und den Round Befehl weg lasse, aber dann zeichnet es ja nicht richtig. ICh bin ziemlicher Anfänger, vlt. ist einfach irgendwo ein Fehler, den ich nicht sehe, ich hoffe mal ihr könnt mir das erklären :)
LineTo (PenPos.X+ Round((Breite-BZ)/2), PenPos.Y-(Breite-BZ));
Hier der restliche Programm Text:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TForm1 = class(TForm) ImZeichnen: TImage; Zeichnen: TButton; procedure ZeichnenClick(Sender: TObject); private { Private declarations } procedure DreieckZeichnen (Ebenen: Integer; Breite: Integer; X1,Y1: Integer); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.DreieckZeichnen(Ebenen: Integer; Breite: Integer; X1,Y1: Integer); var BZ: Integer; begin BZ := Round (Breite/Ebenen); with ImZeichnen.Canvas do begin MoveTo (x1,y1); LineTo (PenPos.X+Round (Breite/2), PenPos.Y-Breite); LineTo (PenPos.X+Round (Breite/2), PenPos.Y+Breite); LineTo (x1,y1); while PenPos.X < Breite do begin MoveTo (x1+BZ,y1); LineTo (PenPos.X+ Round((Breite-BZ)/2), PenPos.Y-(Breite-BZ)); end; end; end; procedure TForm1.ZeichnenClick(Sender: TObject); begin DreieckZeichnen (7,100,0,100); end; end. |
Re: Geschriebenes Programm stürzt ab
Damit ihr wisst, wie die Pyramide aussehen soll:
![]() Ich wollte so vorgehen, dass ich erst die Pyramide zeichne (was auch geklappt hat) und dann die Striche einzelnd zeichne. Die Variable Ebenen gibt dabei an, wieviele dieser Striche es gibt (auf dem Bild also 5, in meinem Programm sind es 7), die Variable Breite gibt an, wie breit die Grundpyramide ist, also von linker, unterer Ecke bis rechte, untere Ecke. Die Variable BZ steht für BreiteZeichnen (hat sich unser Info-Lehrer ausgedacht und es ist unverständlich, ich weiß:D), es ist eine Variable, die den Abstand zwischen den Linien angibt, also immer Breite durch Ebenen, wie ich es geschrieben habe. Ich hoffe das hilft euch, damit ihr mir helfen könnt, weil ich schreib morgen ne Klausur und das wäre echt wichtig :wink: :wink: |
Re: Geschriebenes Programm stürzt ab
Erstmal herzlich willkommen in der DP :dp:
Ich vermute mal, daß du aus der while-Schleife nicht herauskommst. So kannst du es testen: Starte das Programm mit F7 (Einzelschrittmodus): Dann siehst du evtl. wo der Compiler Schwierigkeiten hat. Grüß Wolfgang |
Re: Geschriebenes Programm stürzt ab
Dem ist so, da weder Breite noch PenPos.x sich in der Schleife ändern.
Gruß K-H |
Re: Geschriebenes Programm stürzt ab
Danke :thumb: :thumb:
|
Re: Geschriebenes Programm stürzt ab
Sorry, nochmal ich... Ich kriege partout keine Schleife, ob while oder for, hin, die automatisch mit den gegebenen Variablen die Linien zeichnet, ohne für jede Linie jedesmal einen neuen Befehl einzugeben (was ja die Schleifen unnütz machen würde...). Habt ihr da irgendeine Idee? Ich wäre echt dankbar...
|
Re: Geschriebenes Programm stürzt ab
Als kleiner Denkanstoß:
Delphi-Quellcode:
Bevor Du Dich beschwerst, das ist immer noch eine Endlosschleife, aber es tut sich etwas und es entsteht nicht der Eindruck da wäre irgendetwas "abgeschmiert".
...
while PenPos.X < Breite do begin //MoveTo (x1+BZ,y1); inc(x1,bz); {--- ohne Änderung der Koordinate keine Bewegung} moveto(x1,y1); LineTo (PenPos.X+ Round((Breite-BZ)/2), PenPos.Y-(Breite-BZ)); form1.repaint; {-- Denn sieht man was "gezeichnet" wurde} end; Mir erschließt sich allerdings immer noch nicht so ganz was Du eigentlich willst. Die Aufgabenstellung war doch wohl Zeichne Dreieck ABC Zeichne weitere Dreiecke die "innerhalb ABC liegen". Du benötigst also nur eine Dreieckszeichenroutine, die mehrmals mit den passenden Parametern aufgerufen wird. Gruß K-H |
Re: Geschriebenes Programm stürzt ab
Liste der Anhänge anzeigen (Anzahl: 1)
Ich würde es anders angehen.
Du weisst, wieviele Ebenen das Dreieck haben muss. Diese Ebenen würde ich einzeln Zeichen - und zwar genau drei mal (für jede Seite der Pyramide). Denn das sind interessanterweise auch genau die Linien, die einmal durch die Pyramide laufen ;-) Ich nehme Dein Bild als Basis. Pro Ebene zeichnest Du 5 mal drei Linien (Blau, Orange, Grün, Violett, Rot). In dem Bild sind das eben 5, bei Dir wären das dann eben 2 mehr. A. 1.) Die Grundlinie (Blau) 2.) Die zweite schräge 'Grundlinie' rechts (Startpunkt = Endpunkt der Grundlinie) um beta (im Gegenuhrzeigersinn) gedreht. 3.) Die dritte schräge 'Grundlinie' links (Startpunkt = Endpunkt von 2.), um gamma (im Gegenuhrzeigersinn) gedreht. B. Dann im nächsten Durchlauf berechnest Du die nächst kürzere Linie eine Ebene über der Grundlinie (Orange). Sie ist genau 1/5 kürzer (beginnt also (1/2)*(1/5) weiter rechts von der Grundlinie) und liegt genau das h einer der kleinen Pyramiden (nach Höhensatz von Euklid) darüber. Auch diese Linie drehst Du nun um beta und positionierst sie um die entsprechenden Werte ausgehend von der zweiten Grundlinie. Das gleiche wieder für die dritte Seite. C. Das Spiel beginn von Vorne. Du verkürzt die Linie um 1/5 und setzt sie um h nach oben und 1/2 * 1/5 nach rechts. Das gleiche wieder für die zwei anderen gedrehten Linien. Und so weiter. Bis Du alle 5 Ebenen hast - damit bist Du komplett fertig. |
Re: Geschriebenes Programm stürzt ab
Vielleicht etwas zum grundsätzlichen Verständnis:
1. Bedingte Schleifen (also while und repeat/until) sollten in Folge der (Schleifen-)Bedingung (i.d.R.) mehr als einen Durchlauf ausführen - ansonsten ist die Schleifenkonstruktion überflüssig. 2. Die am Schleifenanfang bzw. -ende abgefragte (einfache oder zusammgesetzte) Bedingungsvariable muß sich in Folge der Aktionen innerhalb der Schleife irgendwann ändern, ansonsten wird es tatsächlich eine Endlosschleife (die nur in sehr speziellen Fällen beabsichtigt ist). Edit: Die Diskussionsüberschrift halte ich für irreführend. Abstürze sind n.m.W. daran gekennzeichnet, daß ein Programm sich beendet (z.B. einfach aus dem Speicher verschwindet oder mit Fehler abbricht). Was Sie meinen, ist eher ein „Aufhängen“ (genau das gleiche blumig-metaphorische Umschreiben wie das Abstürzen), was man auch z.B. mit „verfängt sich in nicht abbrechenbarer Endlosschleife“ oder kürzer „Nicht abbrechenbare, endlose While-Schleife“ besser beschreiben kann. Daß es ein Programm ist, ist zwar nicht zwingend, denn es könnte auch eine DLL sein, jedoch schon aus Häufigkeitsgründen naheliegend (also ziemlich überflüssig), und daß dieses geschrieben wurde.....wer hätte das gedacht. Vielleicht könnten Sie bitte die Suche anderer erleichtern und den Titel etwas aussagekräftiger (um-)formulieren. |
Re: Geschriebenes Programm stürzt ab
Da hier keiner mehr Antwortet und mir langweilig war:
Delphi-Quellcode:
Form1 kann durch beliebige Komponenete ersetzt werden solange diese .Canvas beherscht.
private
procedure Pyramide_paint(grundflaeche, anzahl_ebenen: Integer); procedure TForm1.Pyramide_paint(grundflaeche, anzahl_ebenen: Integer); var i, i2, hoehe, grundflaeche_halb: integer; begin //Bug entfernt. if frac(grundflaeche / 2) <> 0 then grundflaeche := grundflaeche -1; hoehe := trunc((grundflaeche * sqrt(3)) /2); grundflaeche_halb := grundflaeche / 2; with Form1 do begin Canvas.Pen.Color := clBlack; for i := 0 to anzahl_ebenen -1 do begin Canvas.MoveTo(0 + grundflaeche_halb * i, hoehe * (anzahl_ebenen - i)); for i2 := 0 to (anzahl_ebenen -1) - i do begin Canvas.MoveTo(Canvas.PenPos.X + grundflaeche, Canvas.PenPos.Y); Canvas.LineTo(Canvas.PenPos.X - grundflaeche_halb, Canvas.PenPos.Y - hoehe); Canvas.LineTo(Canvas.PenPos.X - grundflaeche_halb, Canvas.PenPos.Y + hoehe); Canvas.LineTo(Canvas.PenPos.X + grundflaeche, Canvas.PenPos.Y); end; end; end; end; // Aufruf könnte so aussehen: Pyramide_paint(100, 3); Ich würde empfehlen mich mal über die richtige Methode zum Konvertieren von Double in int zu informieren und es entsprechend zu ändern. Unter umständen wird es dir auch ein erfahrenes Mitglied verraten. ;) mfg nic |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:14 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