Autor |
Beitrag |
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: Mo 13.12.10 23:26
Hallo Leute,
ich versuche seit einigen Wochen eine Simulation einer Straßenkreuzung zu programmieren.
Im Hintergrund liegt ein TImage der Straße (gemaltes jpg); auf dieser sollen sich 4 weitere TImages bewegen, die Autos. Diese bewegen sich indem ich logischerweise ihre Left und Top Position entsprechend verändere.
Außerdem wird die Ampelschaltzeit beachtet (Ampel Rot - Auto steht!). Dies ist aber für mein Problem eher weniger von Belang, da diese Funktionen schon funktionieren.
Nun habe ich aber das Problem, dass die Autos ineinander (d.h. auf der Oberfläche: übereinander) fahren.
Die TImages schieben sich übereinander.
Deshalb habe ich eine Prozedur geschrieben, welche den Abstand der Autos überprüfen soll und wenn erforderlich anhält.
Es ist ziemlich schwer zu beschreiben, deshalb poste ich einfach mal ein paar Abschnitte aus dem Quelltext und eine .exe.
Ein Timer entscheidet, ob ein Auto bewegt werden soll oder nicht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| procedure TFormGUI.TimerDriveTimer(Sender: TObject); var i:integer; begin for i:= 0 to 3 do begin if((car[i].Left = way[carrier[i]][1][0]) and (car[i].Top = way[carrier[i]][1][1])) then begin spreadCars(i); end else if((UnitDrive.goX(i) = true) and (trafficX = false) and (UnitDrive.onStopLine(i) = true)) then begin end else if((UnitDrive.goX(i) = false) and (trafficY = false) and (UnitDrive.onStopLine(i) = true)) then begin end else if stop[i] then begin end else begin UnitDrive.Drive(i, carrier[i]); end; end; end; |
Ob das Array stop[] true oder falls ist wird in folgender Prozedur festgelegt:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| procedure checkGap(c:integer); var gapMin, gapMax, i:integer; begin gapMin := 20; gapMax := 50; for i:=0 to 3 do if not i = c then case carrier[c] of 4, 5, 6: begin if(UnitGUI.car[c].Left - UnitGUI.car[i].Left < gapMax) and (UnitGUI.car[c].Left - UnitGUI.car[i].Left > gapMin) then UnitGUI.stop[c] := true; end; 10,11,12: begin if(UnitGUI.car[i].Left - UnitGUI.car[c].Left < gapMax) and (UnitGUI.car[i].Left - UnitGUI.car[c].Left > gapMin) then UnitGUI.stop[c] := true; end; 1, 2, 3: begin if(UnitGUI.car[c].Top - UnitGUI.car[i].Top < gapMax) and (UnitGUI.car[c].Top - UnitGUI.car[i].Top > gapMin) then UnitGUI.stop[c] := true; end; 7, 8, 9: begin if(UnitGUI.car[i].Top - UnitGUI.car[c].Top < gapMax) and (UnitGUI.car[i].Top - UnitGUI.car[c].Top > gapMin) then UnitGUI.stop[c] := true; end; end;
end; |
Ja, auf jeden Fall funktioniert es nicht und die Autos schieben sich immer noch übereinandern.
Weiß jemand von euch vielleicht eine Lösung für mein Problem.
Für Hilfe wär ich sehr dankbar!!
[/delphi]
Falls ihr nich irgendwelche Codeschnipsel braucht, sagt bescheid!
Mfg.
rotte
Einloggen, um Attachments anzusehen!
|
|
bummi
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Di 14.12.10 00:23
nicht daß ich es verstanden hätte, aber müßte es nicht
Delphi-Quelltext 1:
| UnitGUI.stop[i] := true |
statt
Delphi-Quelltext 1:
| UnitGUI.stop[c] := true |
heißen
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: Di 14.12.10 00:59
Erstmal danke für die schnelle Antwort.
Nein, das ist es leider nicht.
Ich versuche nochmal die Prozedur genauer zu erläutern:
1. Das Programm soll überprüfen ob sich beispielsweise in der Nähe von Auto 1, welches den Weg 4 nimmt,
ein weiteres Auto befindet. Wenn Ja, soll Auto 1 stehen bleiben.
2. Also überprüfe ich für Auto 1: checkGap(1)
2.1. Durch die For-Schleife wird der Block für jedes Auto (TImage) einmal ausgeführt.
Nur Auto 1 wird logischerweise ausgelassen (if not i = c then)
2.2. Wenn der vorgegeben Weg (carrier[1]) z.B. 4 ist, dann überprüft er spezifisch für diesen Weg.
(Weg 4: von rechts noch oben. D.h. ein störendes Auto könnte sich weniger Left als Auto 1 befinden)
2.3. Wenn der dies zutrifft und der Abstand zu gering ist, wird stop[1] (Auto 1) zu true.
3. Ist stop[1] (Auto 1) true, dann soll Auto 1 stehen bleiben
Ich hoffe das war jetzt aufschlussreich!?
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 14.12.10 14:23
Warum überprüfst du auf maxabstand(gabMax) zum vorgänger Auto? Reicht es nicht aus, nur auf den Mindestabstand(gabMin) zu prüfen um dann zu stoppen, wenn der Abstand kleiner ist? Denn, wenn vor einem nichts ist, brauch ich auch nicht auf den maxabstand zu prüfen!? Oder sollte ich dies falsch verstanden haben?
Ich bin fast überzeugt das der vergleich auf gabMax überflüssig ist!
Gruss ALf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: Di 14.12.10 14:46
Habe es jetzt so versucht, wie du es gesagt hast.
Natürlich hast du wohl recht dass der maximale Abstand überflüssig ist.
Leider hat sich nichts verändert...
Der Quelltext sieht jetzt so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
| procedure checkGap(c:integer); var gapMin, i:integer; begin gapMin := 20;
for i:=0 to 3 do if not i = c then case carrier[c] of 4, 5, 6: begin if(UnitGUI.car[c].Left - UnitGUI.car[i].Left > gapMin) then UnitGUI.stop[c] := true; end; 10,11,12: begin if(UnitGUI.car[i].Left - UnitGUI.car[c].Left > gapMin) then UnitGUI.stop[c] := true; end; 1, 2, 3: begin if(UnitGUI.car[c].Top - UnitGUI.car[i].Top > gapMin) then UnitGUI.stop[c] := true; end; 7, 8, 9: begin if(UnitGUI.car[i].Top - UnitGUI.car[c].Top > gapMin) then UnitGUI.stop[c] := true; end; end; |
Joa, noch jemand ne Idee?
Ich hänge nochmal eine erneuerte exe an.
Einloggen, um Attachments anzusehen!
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 14.12.10 15:02
Mach mal bitte folgendes. Nehme zum test nur mal die TopWerte, klammer die anderen mal aus, und sieh was passiert.
Setzt ein label rein und lass dir das Ergebnis der subtraktion anzeigen und vergleiche es mit gabMin!
Beispiel: 1auto unten steht an Ampel, 2auto von unten kommt dazu und nun das Ergebnis von den beiden Topwerten zum gabMin!
edit: mach den vergleich so als Beispiel,
Delphi-Quelltext 1: 2: 3: 4:
| if UnitGUI.car[c].Top < (UnitGUI.car[i].Top + gapMin) then UnitGUI.stop[c] := true; |
gabMin sollte den Wert haben die die Bildhöhe bzw Bildbreite entspricht.
kleine Anmerkung: Umschalten auf Grün sollte etwas Zeitverzögert sein. (Die Kreuzung ist ja noch nicht frei)
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: Di 14.12.10 17:16
Hmh ok.
Wollte mir jetzt das Ergebnis in Labels ausgeben lassen.
Anscheinend führt er Case nicht aus,
denn die Labels bleiben leer.
Dann habe ich an meinem if not i = c rumgespielt.
Gibt es einen unterschied zwischen
if not i = c then Delphi-Quelltext
und
if not (i = c) then ??
Bei letzterem führt er Case aus, kommt aber zu eigenartigen Ergebnissen.
Naja Resultat aus der Änderung - Die Autos bleiben schon beim Platzieren stehen,
weil sie sich selbst für ein blockierendes Auto halten
Zudem habe ich auch das hier ausprobiert:
Delphi-Quelltext 1: 2: 3: 4:
| if UnitGUI.car[c].Top < (UnitGUI.car[i].Top + gapMin) then UnitGUI.stop[c] := true; |
Klingt eigentlich logisch - leider aber auch keinen Erfolg.
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mi 15.12.10 19:30
So, hab noch ein bischen Zeit
Delphi-Quelltext 1: 2:
| If not i = c then if i <> c then |
Was das andere betrifft, so bin ich der Meinung, das Du eigentlich nur prüfern musst ob sich 2(oder mehr) Bilder(Autos) sich in gleicher Fahrtichtung befinden. Wenn ja, dann Prüfen auf Abstand.
Oder generell prüfen ob etwas davor ist. In etwa so, Prüfen ob ein Bild(Auto) xPixel davor ist. Dabei spielt es keine Rolle welches davor ist. Wichtig ist ebend das nix davor ist!
Also z.B. Auto_1, Auto_2
fahren von unten nach oben. Also muss left für alle die, die diese Strecken fahren gleich sein.
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| if ((auto_1.top-minGab) < als alle anderen auf dieser strecke.top) and (auto_1.left = alle anderen auf dieser strecke.left)then stop else if ((Auto_2.top-minGab) < als alle anderen auf dieser strecke.top) and (auto_2.left = alle anderen auf dieser strecke.left) then stop else |
Ist nur auf die schnelle ein Gedanke. Gibt sicherlich noch ein besseren allgo dafür!
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: Mi 15.12.10 20:44
Hey,
erstmal danke für deine Hilfe,
denn ich muss sagen, dass ich so der Lösung ein Stück näher gekommen bin.
Nach deinem Tipp habe ich jetzt folgendes geschrieben:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| procedure checkGap(c:integer); var gapMin, i:integer; begin gapMin := 50;
for i:=0 to 3 do if i <> c then case carrier[c] of 1, 2, 3: begin if ((UnitGUI.car[c].Top - gapMin) < UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) and ((UnitGUI.carrier[i] = 1) or (UnitGUI.carrier[i] = 2) or (UnitGUI.carrier[i] = 3)) then UnitGUI.stop[c] := true; end; 4, 5, 6: begin if ((UnitGUI.car[c].Left + gapMin) < UnitGUI.car[i].Left) and (UnitGUI.car[c].Top = UnitGUI.car[i].Top) and ((UnitGUI.carrier[i] = 4) or (UnitGUI.carrier[i] = 5) or (UnitGUI.carrier[i] = 6)) then UnitGUI.stop[c] := true; end; 7, 8, 9: begin if ((UnitGUI.car[c].Top + gapMin) < UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) and ((UnitGUI.carrier[i] = 7) or (UnitGUI.carrier[i] = 8) or (UnitGUI.carrier[i] = 9)) then UnitGUI.stop[c] := true; end; 10,11,12:begin if ((UnitGUI.car[c].Left - gapMin) < UnitGUI.car[i].Left) and (UnitGUI.car[c].Top = UnitGUI.car[i].Top) and ((UnitGUI.carrier[i] = 10) or (UnitGUI.carrier[i] = 11) or (UnitGUI.carrier[i] = 12)) then UnitGUI.stop[c] := true; end; end;
end; |
Glaube das ist das, was du meintest.
Daraus ergibt sich leider wieder ein Problem:
Die Autos fahren und bleiben manchmal willkürlich stehen, auch wenn kein Anderes in der Nähe ist.
In den Left und Top Werten, welche ich mir für jedes Auto ausgeben lasse, kann ich sehen,
dass in manchen Fällen wirklich nicht gestoppt werden sollte.
Woran kann das liegen?
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Do 16.12.10 01:02
Warum hast Du jetzt or drin, das erledigt doch die for schleife!?
Delphi-Quelltext 1:
| if ((UnitGUI.car[c].Top - gapMin) < UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) then | reicht, setzt aber vorraus das (c) hinter (i) ist, bei dieser Abfrage. Beim nächsten zyklus muss für c natürlich ein anderes Auto stehen sonst funct das auch nicht! Theoretisch und glaube auch praktisch müssen es 2 for schleifen werden:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| for c:= 0 to 3 do begin for i:= 0 to 3 do begin if i <> c then ....... ....... end; end; | weil Du ja nicht weist, ob c immer hinter den anderen ist. Es kann ja auch sein, bei Deiner Abfrage, das c vor den anderen ist. So würden ja die anderen die hinter c sind nicht stehen bleiben!
Und wenn ich es richtig sehe brauchst du auch nicht das
Delphi-Quelltext es reicht aus wenn Du generell nur abfragst auf Abstand für alle Autos
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| for c:= 0 to 3 do begin for i:= 0 to 3 do begin if i <> c then begin if ((UnitGUI.car[c].Top - gapMin) < UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left + gapMin) < UnitGUI.car[i].Left) and (UnitGUI.car[c].Top = UnitGUI.car[i].Top) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Top + gapMin) < UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left - gapMin) < UnitGUI.car[i].Left) and (UnitGUI.car[c].Top = UnitGUI.car[i].Top) then UnitGUI.stop[c]:= true; end; end; end; | ungetestet!
Aber so würdest Du unabhängig generell alle Autos auf allen Strassen überprüfen auf Abstand.
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
Für diesen Beitrag haben gedankt: rotte
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: Do 16.12.10 12:23
Also mit dem or will ich überprüfen ob ein blockierendes Auto den gleichen Startpunkt, wie das abgefragte Auto hat.
Die zweite Schleife, die du eingebaut hast, ist dort leider überflüssig, da c schon immer im Timer ersetzt wird -
Siehe meinen ersten Post bei procedure TFormGUI.TimerDriveTimer(Sender: TObject);.
Die case Anweisung muss auch drin bleiben, da sonst ja in alle Richtungen überprüft wird.
So werden dann auch Autos als störend empfunden, die eigentlich gar nicht auf dem Weg liegen
Hmh, kann es sein, dass evtl was mit den Anweisungen in Case nicht stimmt, also dass er was falsches überprüft.??
Ich bin sie alle durchgegangen, aber trotzdem habe ich das Gefühl, dass da was falsch sein könnte.
(Left wird nach rechts größer, Top wird nach unten größer.) ??
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Do 16.12.10 12:52
rotte hat folgendes geschrieben : | Die case Anweisung muss auch drin bleiben, da sonst ja in alle Richtungen überprüft wird. |
soll ja auch so sein. Die Strecke ist ja nur bedingt notwendig. Wichtig ist doch das nix davor ist
rotte hat folgendes geschrieben : | So werden dann auch Autos als störend empfunden, die eigentlich gar nicht auf dem Weg liegen |
ist nicht ganz richtig. Der vergleich mit top < top and left = left z.B überprüft ja ob ein anderes die gleich Strecke benutzt! Left von oben nach unten hat einen anderen Wert, als left von unten nach oben
rotte hat folgendes geschrieben : | Hmh, kann es sein, dass evtl was mit den Anweisungen in Case nicht stimmt, also dass er was falsches überprüft.?? |
Darum lass die case auch weg, sondern prüfe generell alle strecken.
rotte hat folgendes geschrieben : | Ich bin sie alle durchgegangen, aber trotzdem habe ich das Gefühl, dass da was falsch sein könnte.
(Left wird nach rechts größer, Top wird nach unten größer.) ?? |
ist ja auch richtig, da Du ja links bei 0 anfängst zu zählen wenn es nach rechts fährt und top von 0 anfängt wenn es nach unten fährt.
Umgekehrte Richtung werden die Werte zu 0 also kleiner.
Sorry: an den Timer hab ich nicht mehr gedacht.
Gruss ALf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: Do 16.12.10 13:33
Ok leuchtet mir ein.
Habe es jetzt nach deinen Tipps umgeschrieben.
Leider funktioniert es immer noch nicht.
das steht jetzt in checkGap():
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| gapMin := 100;
for i:= 0 to 3 do begin if i <> c then begin if ((UnitGUI.car[c].Top - gapMin) < UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left + gapMin) < UnitGUI.car[i].Left) and (UnitGUI.car[c].Top = UnitGUI.car[i].Top) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Top + gapMin) < UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left - gapMin) < UnitGUI.car[i].Left) and (UnitGUI.car[c].Top = UnitGUI.car[i].Top) then UnitGUI.stop[c]:= true else UnitGUI.stop[c]:= false; end; end; |
Ich hänge mal die aktuelle exe an. Vllt kannst du mal bei gelegenheit reinschauen??
Einloggen, um Attachments anzusehen!
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Do 16.12.10 14:08
Habs mal durchlaufen lassen. Ab den Photo passiert nix mehr obwohl Car2, Car4 ja fahren dürften. Stimmt also die gesamte Abfrage nicht. mh.... irgend wo noch was übersehen
Selbst wenn car4 links abbiegen möchte muss car2 weiter Fahren!!!!
Denn car2 top, left hat keine kollision mit irgend ein anderes?
Als Test würde ich empfehlen erstmal nur in 2 Richtungen festzulegen von oben nach unten, von unten nach oben dann von links nach rechts und von recht nach links. So kann man besser nachvollziehen wo an welcher Stelle es zu überschneidungen kommt bzw. ob die If's überhaupt alles richtig berücksichtigen!?
Hab auch das gefühl das nicht ganz klar ist welches Auto vor welchem ist.
So nach und nach glaube ich das es besser ist i zu stoppen nicht c, wie @bummi es schon gesagt hat!
Kommt noch hinzu das die Grünschaltung zu Zeitig kommt(Kreuzung ist nicht Frei)! Was aber natürlich auch zum Stop führen muss wenn ein Fahrzeug also noch davor ist egal aus welcher Richtung! mh...?
Gib Bitte mal im DebugPanel noch eine Info aus, für jedes Auto, an welcher Stelle gerade die Kollisions abfrage ist!
So kann man auch leichter sehen welches Auto (c) gerade abgefragt wird.
EDit: hab den Fehler eventuell gefunden, hab aber keine Zeit das genau aufzuschlüsseln, erst ab 23:00 bin ich wieder da!
EDit2: so hab die Reihenfolge der Abfragen mal sortiert. Müsste theoretisch jetzt funcen!?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| gapMin:= 100; for i:= 0 to 3 do begin if i <> c then begin if ((UnitGUI.car[c].Top + gapMin) > UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Top - gapMin) < UnitGUI.car[i].Top) and (UnitGUI.car[c].Left = UnitGUI.car[i].Left) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left + gapMin) > UnitGUI.car[i].Left) and (UnitGUI.car[c].Top = UnitGUI.car[i].Top) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left - gapMin) < UnitGUI.car[i].Left) and (UnitGUI.car[c].Top = UnitGUI.car[i].Top) then UnitGUI.stop[c]:= true else UnitGUI.stop[c]:= false; end; end; |
Gruss ALf
Einloggen, um Attachments anzusehen!
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: Fr 17.12.10 16:22
Wow, vielen vielen Dank für deine Mühe,
aber leider funktionierts immer noch nicht richtig.
Die Autos scheinen gut zu stoppen, wenn vor ihnen ein Anderes in der Bahn ist
(Bis auf den Startpunkt oben, da geht es nicht - sollte aber nur ein Vorzeichenproblem sein).
Das größere Problem ist, dass die Autos jetzt zu sensibel sind. D.h. auch stoppen,
wenn irgendwo in der Umgebung ein anderes Auto ist, was sie gar nicht behindert.
Wie kann man das lösen?
Einloggen, um Attachments anzusehen!
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Fr 17.12.10 16:53
Rofl, hab gerade eine Sittuation das alle auf einer ebene sind (alle Top sind gleich) aber kein left Wert ist gleich bzw -+100 mh.... befinden sich alle auf der Spur von rechts nach links
Car1 Current L -87 top184
car2 current L584 top184
car3 current L312 top184
car4 current L64 top184
nun ist natürlich klar das bei der Abfrage von links nach rechts, Left von car2-4 grösser sind als car1. Also benötigen wir einen dritten Wert der festlegt was gültig ist. Und zwar die die Spur nicht den Weg! den die Fahrzeuge nehmen!
bin gerade dabei dies richtig zu machen melde mich wieder.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| Leftou:= 184;Leftuo:= 312; Toplr:= 312; Toprl:= 184; gapMin:= 100; for i:= 0 to 3 do begin if i <> c then begin if ((UnitGUI.car[c].Top + gapMin) = UnitGUI.car[i].Top) and ((UnitGUI.car[c].Left = Leftou) and (UnitGUI.car[i].Left = Leftou)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Top - gapMin) = UnitGUI.car[i].Top) and ((UnitGUI.car[c].Left = Leftuo) and (UnitGUI.car[i].Left = Leftuo)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left + gapMin) = UnitGUI.car[i].Left) and ((UnitGUI.car[c].Top = Toplr) and (UnitGUI.car[i].Top = Toplr)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left - gapMin) = UnitGUI.car[i].Left) and ((UnitGUI.car[c].Top = Toprl) and (UnitGUI.car[i].Top = Toprl)) then UnitGUI.stop[c]:= true else UnitGUI.stop[c]:= false; end; end; |
kurze Erklärung dazu
Nun wird noch geprüft ob die Fahrzeuge die gleich Spur benutzen. Wenn ja, muss der Abstand nicht auf grösser oder kleiner getestet werden sonder auf gleich mit den eventuell davor fahrenden Auto. gabMin dürfte sicherlich die grösse des Pictures sein. Wenn der Test auf Abstand nach jeder neuen vergebenen Position durch geführt wird funct es.
So brauch man in diesem Fall nicht die negativ Werte berücksichtigen. Ich hoffe das meine Überlegung jetzt richtig sind!
Gruss ALf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: So 19.12.10 18:54
Hey,
danke für deine Lösung und @ALF sorry für die verwirrende PN,
habe den neuen Post jetzt erst gesehen
Es funktioniert jetzt zumindest schonmal auf der X-Achse (also l->r und r->l).
Leider aber nicht auf der Y-Achse.
Irgendwo muss noch ein Fehler sitzen.
Kann mir aber nicht vorstellen wo:
Die Koordinaten in den obigen Variablen stimmen und die Abfrage scheint auch einleuchtend.
Btw was meinst du mit: Zitat: | //nur wenn die Graphic so bleibt ansonsten muss angepasst werden |
???
Sieht jetzt so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| procedure checkGap(c:integer); var gapMin, i, Leftou, Leftuo,Toplr,Toprl:integer; begin
Leftou:= 184;Leftuo:= 312; Toplr:= 312; Toprl:= 184; gapMin:= 100; for i:= 0 to 3 do begin if i <> c then begin if ((UnitGUI.car[c].Top + gapMin) = UnitGUI.car[i].Top) and ((UnitGUI.car[c].Left = Leftou) and (UnitGUI.car[i].Left = Leftou)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Top - gapMin) = UnitGUI.car[i].Top) and ((UnitGUI.car[c].Left = Leftuo) and (UnitGUI.car[i].Left = Leftuo)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left + gapMin) = UnitGUI.car[i].Left) and ((UnitGUI.car[c].Top = Toplr) and (UnitGUI.car[i].Top = Toplr)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left - gapMin) = UnitGUI.car[i].Left) and ((UnitGUI.car[c].Top = Toprl) and (UnitGUI.car[i].Top = Toprl)) then UnitGUI.stop[c]:= true else UnitGUI.stop[c]:= false; end; end;
end; |
???
Edit: Ups sorry, scheint doch irgendwie nur beim ersten Mal zu funktionieren.
Bei folgenden Abfragen schieben die Autos sich wieder aufeinander.
Jetzt bin ich komplett verwirrt???
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: So 19.12.10 19:22
jo, den Fehler kann ich nach vollziehen.
Darum hatte ich auch schon mal gesagt das Du 2 Forschleifen machen musst! Grund, wenn Du auf Abstand prüfst solltest Du alle Prüfen, nicht nur den einen. Dann erst neue Posi setzten und dann wieder Prüfen!
Du Prüfst einen, veränderst positionen, prüfst einen anderen, veränderst posi usw.
Bei 4 stück hat der erste seine posi um 4 verändert wenn er wieder dran ist!
Mit '> <' geht es auch, nur müssen dann noch weitere Vergleiche gemacht werden, die dann auf Gleichheit testen. Darum mache es Bitte mit der letzten version + den 2 For schleifen, dann wird es auch funcen.
rotte hat folgendes geschrieben : | Btw was meinst du mit: Zitat: | //nur wenn die Graphic so bleibt ansonsten muss angepasst werden | ??? |
Solltest Du die Strassen positionen verändern muss dies dort auch angepasst werden.
Gruss ALf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
rotte
Hält's aus hier
Beiträge: 10
|
Verfasst: So 19.12.10 20:51
Hmh es geht immer noch nicht.
Es wird immer noch nicht ordnungsgemäß angehalten.
Auf der X-Achse funktioniert es wie vorher manchmal.
Auf der Y-Achse geht nichts.
Außerdem wenn zwei Autos hintereinander stehen, und 2 angehalten hat und dann ein drittes hinzu kommt,
fährt es über das Zweite.
Irgendwie scheint es so als wäre es eher zufällig ob die Autos halten oder nicht.
Hab das jetzt mit den zwei Schleifen gemacht:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
| procedure checkGap(c:integer); var gapMin, i, Leftou, Leftuo,Toplr,Toprl:integer; begin
Leftou:= 184;Leftuo:= 312; Toplr:= 312; Toprl:= 184; gapMin:= 100;
for c:= 0 to 3 do for i:= 0 to 3 do begin if i <> c then begin if ((UnitGUI.car[c].Top + gapMin) = UnitGUI.car[i].Top) and ((UnitGUI.car[c].Left = Leftou) and (UnitGUI.car[i].Left = Leftou)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Top - gapMin) = UnitGUI.car[i].Top) and ((UnitGUI.car[c].Left = Leftuo) and (UnitGUI.car[i].Left = Leftuo)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left + gapMin) = UnitGUI.car[i].Left) and ((UnitGUI.car[c].Top = Toplr) and (UnitGUI.car[i].Top = Toplr)) then UnitGUI.stop[c]:= true else if ((UnitGUI.car[c].Left - gapMin) = UnitGUI.car[i].Left) and ((UnitGUI.car[c].Top = Toprl) and (UnitGUI.car[i].Top = Toprl)) then UnitGUI.stop[c]:= true else UnitGUI.stop[c]:= false; end; end;
end; |
Einloggen, um Attachments anzusehen!
|
|
|