AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Freien Platz ermitteln

Ein Thema von VkPenguin · begonnen am 27. Dez 2011 · letzter Beitrag vom 31. Dez 2011
Antwort Antwort
Seite 1 von 2  1 2   
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#1

Freien Platz ermitteln

  Alt 27. Dez 2011, 16:53
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:
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;
(Unwichtiges, was ohne zusammenhang nur verwirren würde habe ich zum besseren Verständnis rausgeschnitten)
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

Geändert von VkPenguin (27. Dez 2011 um 17:05 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Freien Platz ermitteln

  Alt 27. Dez 2011, 23:49
1. Abfrage von Bool-Werten
Falsch ist
Delphi-Quellcode:
var IsValid : Boolen;
...
if IsValid = True then
...
if IsValid = False then
Richtig ist:
Delphi-Quellcode:
var IsValid : Boolen;
...
if IsValid then
...
if not IsValid then
2. Integer-Division
So nicht
Delphi-Quellcode:
var IntValue : integer;
...
IntValue := Trunc( IntValue / 2 );
sondern so
Delphi-Quellcode:
var IntValue : integer;
...
IntValue := IntValue div 2;
3. Flächen Operationen (TRect)
Delphi/Windows bringt von Haus aus schon Routinen mit um mit Flächen zu arbeiten.
z.B. Delphi-Referenz durchsuchenIntersectRect

Merk dir also zu jedem Kreis (in einem Array) die Fläche, die dieser Kreis belegt und prüfe diese Liste der Flächen
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (27. Dez 2011 um 23:51 Uhr)
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#3

AW: Freien Platz ermitteln

  Alt 28. Dez 2011, 00:55
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...?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
40.509 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Freien Platz ermitteln

  Alt 28. Dez 2011, 01:19
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?');
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list

Geändert von himitsu (28. Dez 2011 um 01:21 Uhr)
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#5

AW: Freien Platz ermitteln

  Alt 29. Dez 2011, 15:22
Habe die Schreibweisen wie ihr es vorgeschlagen habt gleich überall im Programm geändert, macht einfach mehr Sinn.

@Sir Rufo:
Delphi/Windows bringt von Haus aus schon Routinen mit um mit Flächen zu arbeiten.
z.B. Delphi-Referenz durchsuchenIntersectRect

Merk dir also zu jedem Kreis (in einem Array) die Fläche, die dieser Kreis belegt und prüfe diese Liste der Flächen
war glaub ich ein wirklich guter Tipp. Allerdings konnte ich keine entsprechende Funktion für Kreise finden. Ich könnte zwar für jeden Kreis noch ein temporäres Rechteck erstellen, um damit zu rechnen, aber das ist keine sehr elegante Lösung.

Aber im Prinzip müsste es doch so in der Richtung gehen:
*Pseudo-Code*
Delphi-Quellcode:
For I:=1 To AnzahlDerKreise Do
Begin
Überprüfe überschneidung Kreis(I) und NeuerKreis
If KeineÜberschneidung Then Kreis kann gezeichnet werden
End;
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
 X:=Frei[Random(K)]; //Frei ist das Array mit freien Plätzen Ich weiß allerdings nicht, wie ich das hiermit umsetzen soll. Meint ihr, es ist der richtige Weg, wenn ich in der Richtung weitermache?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
40.509 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Freien Platz ermitteln

  Alt 29. Dez 2011, 15:30
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
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list

Geändert von himitsu (29. Dez 2011 um 15:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Freien Platz ermitteln

  Alt 29. Dez 2011, 20:55
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
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#8

AW: Freien Platz ermitteln

  Alt 30. Dez 2011, 19:14
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 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.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
40.509 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Freien Platz ermitteln

  Alt 30. Dez 2011, 19:18
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list
  Mit Zitat antworten Zitat
VkPenguin

Registriert seit: 23. Dez 2011
150 Beiträge
 
Delphi XE7 Architect
 
#10

AW: Freien Platz ermitteln

  Alt 30. Dez 2011, 19:31
Okay, aber was soll das denn? Ich muss also jede lokale Variable erst initialisieren? Wieder was gelernt
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf