![]() |
Freien Platz ermitteln
Hallo zusammen, ich hab malwieder ein Problem.
Details die keine Rolle spielen lasse ich der einfachheit halber mal Weg, aber im Prinzip habe ich folgendes Problem: Mein Programm soll "Zähler" Kreise der Größe "Groesse" Zeichnen. Diese werden voher festgelegt. Die Y-Achsenposition ist immer gleich. Nun möchte nicht, dass er Kreise übereinanderzeichnet, also reicht KreisXPos:=Random(Bildschirmbreite) nicht. Ich hab schon ein bisschen im Internet gesucht und mir aus dem was ich gefunden hab eine Lösung zusammengebaut, die aber Leider nicht funktioniert.... aber warum? Hab es schon mit debuggen probiert, bin aber nicht dahintergekommen. Hier der entscheidende Codeausschnitt:
Delphi-Quellcode:
(Unwichtiges, was ohne zusammenhang nur verwirren würde habe ich zum besseren Verständnis rausgeschnitten)
Var Frei: Array[1..2000] Of Integer; //Tatsächlich Freie Positionen (Wer hat schon mehr als 2000 Pixel als Auflösung? Ist nicht ideal, aber verfeinerungen kann man ja später noch einfügen.)
Var Belegung: Array [1..2000] of Boolean; // Positionen, die in irgendeiner Form von einem Kreis benutzt werden, nicht unbedingt als Ursprung Procedure XpositionenFestlegen; Var I,k,J,M:Integer; Platz:Boolean; Begin Zähler:=Random(15); //Anzahl der Kreise for I := 1 to Zähler do Begin Platz:=True; K:=0; Kreisanzahl:=Kreisanzahl+1; Groesse:=15; for J:=1 To Bildschirmbreite Do Begin if Belegung[J]=False then Begin Platz:=True; for M:=J-Trunc(Groesse/2) To Trunc(J+Groesse/2) DO //Groesse/2 Da der Radius zur einen und zur anderen Seite gemessen werden soll Begin If Belegung[M]=True Then Platz:=False //Wenn eine benötigten Flächen belegt ist, ist der Platz insgesamt nicht frei End; if (Platz=True) then Begin K:=K+1; Frei[K]:=J; End; End; End; X:=Frei[Random(K)]; K:=0; KreisPosX:=X; For J:=KreisPosX-Trunc(Groesse/2) To (KreisPosX+Trunc(Groesse/2) Do //Fläche, die der neue Kreis einnimmt. Begin Belegung[J]:=True; End; End; End; Meine Frage also: Kann mir jemand einen Tipp geben, was falsch ist oder wie ich das ganze besser machen könnte? Nur bitte keine Perfekte Lösung Posten, die werde ich als Anfänger wohl eh nicht verstehen - dann bringt es mir nichts, auch wenn es lieb gemeint ist. Danke euch :-) |
AW: Freien Platz ermitteln
1. Abfrage von Bool-Werten
Falsch ist
Delphi-Quellcode:
Richtig ist:
var IsValid : Boolen;
... if IsValid = True then ... if IsValid = False then
Delphi-Quellcode:
2. Integer-Division
var IsValid : Boolen;
... if IsValid then ... if not IsValid then So nicht
Delphi-Quellcode:
sondern so
var IntValue : integer;
... IntValue := Trunc( IntValue / 2 );
Delphi-Quellcode:
3. Flächen Operationen (TRect)
var IntValue : integer;
... IntValue := IntValue div 2; Delphi/Windows bringt von Haus aus schon Routinen mit um mit Flächen zu arbeiten. z.B. ![]() Merk dir also zu jedem Kreis (in einem Array) die Fläche, die dieser Kreis belegt und prüfe diese Liste der Flächen |
AW: Freien Platz ermitteln
Hi, danke für deine Antwort! Nur verstehe ich nicht ganz, warum.. Also ich meine, was ist denn der Unterschied zwischen den beiden Varianten? Werde es dann aber ab jetzt so handhaben. Und zu dem dritten: Auch das werd ich mir mal anschaun und dann später (heute nichtmehr :) ) im Programm ändern, ist sicherlich die geschicktere Variante.. Aber ich verstehe dennoch nicht, warum es so, wie ich es gemacht habe, nicht auch geht...?
|
AW: Freien Platz ermitteln
Delphi-Quellcode:
var B: Boolean;
B := Boolean(3); if B = True then ShowMessage('True') else if B = False then ShowMessage('False') else ShowMessage('hmm?'); if B then ShowMessage('2: True') else if not B then ShowMessage('2: False') else ShowMessage('2: hmm?'); |
AW: Freien Platz ermitteln
Habe die Schreibweisen wie ihr es vorgeschlagen habt gleich überall im Programm geändert, macht einfach mehr Sinn.
@Sir Rufo: Zitat:
Aber im Prinzip müsste es doch so in der Richtung gehen: *Pseudo-Code*
Delphi-Quellcode:
Allerdings wäre das ja auch nicht ganz das gelbe vom Ei, denn dann würde das Programm ja solange immer wieder an zufälligen Positionen versuchen, einen Kreis zu zeichnen, bis es irgendwann passt. Besser wäre ja, wenn es ermitteln würde, wo ein Kreis hinpasst und dann eine zufällige Position davon aussuchen würde oder nicht? Das war ja das Ziel von
For I:=1 To AnzahlDerKreise Do
Begin Überprüfe überschneidung Kreis(I) und NeuerKreis If KeineÜberschneidung Then Kreis kann gezeichnet werden End;
Delphi-Quellcode:
Ich weiß allerdings nicht, wie ich das hiermit umsetzen soll. Meint ihr, es ist der richtige Weg, wenn ich in der Richtung weitermache?
X:=Frei[Random(K)]; //Frei ist das Array mit freien Plätzen
|
AW: Freien Platz ermitteln
Wann berühren sich Kreise?
wenn der Abstand = 0 ist oder der Abstand der Mittelpunkte der Summe der Radien entspricht
Delphi-Quellcode:
if Abstand_der_Kreismittelpunkte >= Radius_des_einen_Kreises + Radius_des_andern_Kreises then
passt; // oder if Abstand_der_Kreismittelpunkte - Radius_des_einen_Kreises - Radius_des_andern_Kreises >= 0 then // Abstand größer-gleich 0 passt; PS: Ein Array mit freien Plätzen, wo du nur einen Platz prüfen mußt, das geht nur, wenn - alle Kreise gleich groß - alle Kreise genau auf solchen Plätzen liegen, also in einem definierten Raster |
AW: Freien Platz ermitteln
Die Kreise liegen doch alle auf einer Achse, somit ist es egal, ob du die Kreisfläche oder vereinfacht das umschließende Quadrat des Kreises prüfst ;)
|
AW: Freien Platz ermitteln
Nabend zusammen,
hab mich jetzt nocheinmal eingehend damit beschäftigt und das ganze durch den Debugger laufen lassen. Dabei sind mir zwei Sachen aufgefallen: 1. Der Fehler. Ich weiß garnicht, wie ich so blöd sein kann :P Der Tipp mit "div 2" statt "/2" war ja gut, da ich aber ohnehin den Radius und nicht den Durchmesser als "Größe" festgelegt hatte, war das totaler Blödsinn.. Es funktioniert also jetzt, danke für eure Tipps! :) 2. (Und das ist wirklich seltsam) Für die Procedur habe ich eine lokale Variable deklariert, die AM ANFANG der Procedur, also schon vor dem ersten Zugriff einen gigantischen Wert (etwa: 2012404120) hat. Das kann doch garnicht sein ?! Wenn ich am Anfang "Variable:=0;" eingebe, funktioniert alles. |
AW: Freien Platz ermitteln
2. Wenn du eine Variable nicht initialisierst, dann brauchst du dich nicht wundern, wenn dort ein "zufälliger" Wert drin steht.
Lokale Variablen werden nunmal nicht automatisch intialisiert. :stupid: |
AW: Freien Platz ermitteln
Okay, aber was soll das denn? Ich muss also jede lokale Variable erst initialisieren? Wieder was gelernt :P
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:59 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