Autor Beitrag
rotte
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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:
ausblenden 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 // Für jedes der 4 Autos mache...
  begin
    // Befindet sich das Auto im Ziel
    if((car[i].Left = way[carrier[i]][1][0]) and (car[i].Top = way[carrier[i]][1][1])) then
     begin
       spreadCars(i); // nicht wichtig
     end
    else if((UnitDrive.goX(i) = true) and (trafficX = false) and (UnitDrive.onStopLine(i) = true)) then
     begin
       // Stop X // nicht wichtig
     end
    else if((UnitDrive.goX(i) = false) and (trafficY = false) and (UnitDrive.onStopLine(i) = true)) then
     begin
       // Stop Y // nicht wichtig
     end
    else if stop[i] then /// <--- Wenn Array stop[Auto] ist true dann mache nichts
     begin
       // Abstand halten
     end
    else // <-- andernfalls fahre
     begin
       UnitDrive.Drive(i, carrier[i]);
     end;
  end;
end;


Ob das Array stop[] true oder falls ist wird in folgender Prozedur festgelegt:
ausblenden volle Höhe 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:
31:
32:
33:
34:
35:
procedure checkGap(c:integer); // c = Autonummer
var gapMin, gapMax, i:integer;
begin
 gapMin := 20// minimaler Abstand
 gapMax := 50// maximaler Abstand

 for i:=0 to 3 do // für alle Autos mache...
        if not i = c then // wenn i nicht c, das initiierende Auto
                case carrier[c] of // carrier sind vorgegeben Wege, die das Auto nehmen kann. Die Wege haben Nummern von 1- 12
                        // X-Achse
                        // Wegnummern
                        456begin    // initiierendes Auto  // Gesuchtes Auto
                                   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; // wenn der Abstand zwischen den gapMin und Max dann stop[Auto] := true - Auto steht
                                 end;
                       10,11,12begin
                                   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;
                        // Y-Achse
                        123begin
                                   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;
                        789begin
                                   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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Di 14.12.10 00:23 
nicht daß ich es verstanden hätte, aber müßte es nicht
ausblenden Delphi-Quelltext
1:
UnitGUI.stop[i] := true					

statt
ausblenden Delphi-Quelltext
1:
UnitGUI.stop[c] := true					

heißen

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
rotte Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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:
ausblenden 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
                        // X-Achse
                        456begin
                                   if(UnitGUI.car[c].Left - UnitGUI.car[i].Left > gapMin) then
                                                UnitGUI.stop[c] := true;
                                 end;
                       10,11,12begin
                                   if(UnitGUI.car[i].Left - UnitGUI.car[c].Left > gapMin) then
                                                UnitGUI.stop[c] := true;
                                 end;
                        // Y-Achse
                        123begin
                                   if(UnitGUI.car[c].Top - UnitGUI.car[i].Top > gapMin) then
                                                UnitGUI.stop[c] := true;
                                 end;
                        789begin
                                   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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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,
ausblenden Delphi-Quelltext
1:
2:
3:
4:
//autos die von unten kommen
     //ankommendes Auto                auto was davor steht
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) :wink:
Gruss Alf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
rotte Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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
ausblenden Delphi-Quelltext
1:
					

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 :-D

Zudem habe ich auch das hier ausprobiert:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
//autos die von unten kommen
     //ankommendes Auto                auto was davor steht
if UnitGUI.car[c].Top < (UnitGUI.car[i].Top + gapMin)  then
  UnitGUI.stop[c] := true;


Klingt eigentlich logisch - leider aber auch keinen Erfolg.
ALF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Mi 15.12.10 19:30 
So, hab noch ein bischen Zeit :wink:
ausblenden Delphi-Quelltext
1:
2:
If not i = c then //mhhh... wenn i nicht true = c (true) ???
if i <> c then //müsste eigentlich so  auch richtig sein

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.

ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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:
ausblenden volle Höhe 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:
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
                        // S1
                        123begin
                                   if ((UnitGUI.car[c].Top - gapMin) < UnitGUI.car[i].Top) and
                                      (UnitGUI.car[c].Left = UnitGUI.car[i].Left) and
                                      ((UnitGUI.carrier[i] = 1or (UnitGUI.carrier[i] = 2or (UnitGUI.carrier[i] = 3)) then
                                                UnitGUI.stop[c] := true;
                                 end;
                        // S2
                        456begin
                                   if ((UnitGUI.car[c].Left + gapMin) < UnitGUI.car[i].Left) and
                                      (UnitGUI.car[c].Top = UnitGUI.car[i].Top) and
                                      ((UnitGUI.carrier[i] = 4or (UnitGUI.carrier[i] = 5or (UnitGUI.carrier[i] = 6)) then
                                                UnitGUI.stop[c] := true;
                                 end;
                        // S3
                        789begin
                                   if ((UnitGUI.car[c].Top + gapMin) < UnitGUI.car[i].Top) and
                                      (UnitGUI.car[c].Left = UnitGUI.car[i].Left) and
                                      ((UnitGUI.carrier[i] = 7or (UnitGUI.carrier[i] = 8or (UnitGUI.carrier[i] = 9)) then
                                                UnitGUI.stop[c] := true;
                                 end;
                        10,11,12:begin
                        // S4
                                   if ((UnitGUI.car[c].Left - gapMin) < UnitGUI.car[i].Left) and
                                      (UnitGUI.car[c].Top = UnitGUI.car[i].Top) and
                                      ((UnitGUI.carrier[i] = 10or (UnitGUI.carrier[i] = 11or (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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Do 16.12.10 01:02 
Warum hast Du jetzt or drin, das erledigt doch die for schleife!?
ausblenden 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:

ausblenden 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
ausblenden Delphi-Quelltext
1:
case carrier[c] of					
es reicht aus wenn Du generell nur abfragst auf Abstand für alle Autos
ausblenden 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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Do 16.12.10 12:52 
user profile iconrotte hat folgendes geschrieben Zum zitierten Posting springen:
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

user profile iconrotte hat folgendes geschrieben Zum zitierten Posting springen:
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

user profile iconrotte hat folgendes geschrieben Zum zitierten Posting springen:
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.

user profile iconrotte hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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():
ausblenden 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; // Löst das stop wieder
       end;
   end;


Ich hänge mal die aktuelle exe an. Vllt kannst du mal bei gelegenheit reinschauen??
Einloggen, um Attachments anzusehen!
ALF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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 :gruebel:
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!?
kreuzung

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!?

ausblenden 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     //von oben nach unten                                                   befinden sich auf der gleichen Seite
        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  //von unten nach oben                                                   hier ist Left grösser als oben
        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 //von links nach rechts                                                  hier ist top grösser als unten
        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  //von recht nach links                                                  hier demzufolge kleiner als oben
        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 //wenn gestoppt und nichts mehr davor dann fahre wieder los
            UnitGUI.stop[c]:= false;
    end;
end;
// es kann also immer nur eine Übereinstimmung geben auf der gleichen Strecke, selbst wenn sich ein Fahrzeug noch auf
// der Kreuzung befindet und die Ampel wird Grün muss das anfahrende Fahrzeug warten bis die Position vor ihm frei ist.
// Es kommt dann zwar zu Überlagerung der Bilder. Um dies zu verhindern müsste der Vergleich erweitert werden!
//Wichtig ist das Du Deine Ampelschaltung veränderst!! Sonst kommt es trotzdem auf der Kreuzung zu kollisionen!!!
//Gelb bedeutet die Kreuzung zu räumen nicht sie zu befahren!!! Dies machen aber die Autos noch.

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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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.

ausblenden 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;//nur wenn die Graphic so bleibt ansonsten muss angepasst werden
Leftuo:= 312;
Toplr:= 312;
Toprl:= 184;
gapMin:= 100;
for i:= 0 to 3 do
begin            //es wird nur dann der Abstand geprüft wenn die Fahrzeuge auch in der selben Richtung sind 
    if i <> c then
    begin //von oben nach unten  
        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 //von unten nach oben Left 
        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  //von links nach rechts 
        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  //von rechts nach links 
        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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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 :oops:
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:
ausblenden 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;//nur wenn die Graphic so bleibt ansonsten muss angepasst werden
Leftuo:= 312;
Toplr:= 312;
Toprl:= 184;
gapMin:= 100;
for i:= 0 to 3 do
begin            //es wird nur dann der Abstand geprüft wenn die Fahrzeuge auch in der selben Richtung sind
    if i <> c then
    begin //von oben nach unten
        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 //von unten nach oben Left
        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  //von links nach rechts
        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  //von rechts nach links
        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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: 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.

user profile iconrotte hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 10



BeitragVerfasst: 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:
ausblenden volle Höhe 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:
31:
32:
33:
procedure checkGap(c:integer);
var gapMin, i, Leftou, Leftuo,Toplr,Toprl:integer;
begin

Leftou:= 184;//nur wenn die Graphic so bleibt ansonsten muss angepasst werden
Leftuo:= 312;
Toplr:= 312;
Toprl:= 184;
gapMin:= 100;

for c:= 0 to 3 do
for i:= 0 to 3 do
begin
          //es wird nur dann der Abstand geprüft wenn die Fahrzeuge auch in der selben Richtung sind
    if i <> c then
    begin //von oben nach unten
        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 //von unten nach oben Left
        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  //von links nach rechts
        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  //von rechts nach links
        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!