Auto fährt um die Kurve

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Kannst ja mal versuchen eine Beschleunigung einzubauen daran scheiter ich gerade und es wird wohl wieder 8h vergehen...
ist in arbeit, gebe mir 10min ^^
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

STARGÅTE hat geschrieben:ist in arbeit, gebe mir 10min ^^
Was sag ich? Bild
Nach meiner Uhr noch 5 Minuten... Selbst, wenns 12 oder 13 Minuten werden, SG kann das! (Jetzt ist aber Schluss mit schleimen, AND51!!!!!)
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Fertig^^

Code: Alles auswählen

InitSprite() 
InitSprite3D() 
InitKeyboard() 

OpenScreen(1024, 768, 32, "test") 

CreateSprite(1, 64, 64, #PB_Sprite_Texture) 
StartDrawing(SpriteOutput(1)) 
  Box(0,  16, 32, 32, RGB(192,192,192)) 
  Box(32, 16, 32, 32, #Gray) 
StopDrawing() 
CreateSprite3D(1, 1) 

; startposition Auto 
carx.f = 200 
cary.f = 200 
; startwinkel Auto 
cara.f = 0 
; Geschwindigkeit 
cars.f = 0 
carsmax.f = 5 
carb.f = 0.1

; radabstand 
l = 32 

; lenkeinschlag 
alpha.f = 0*#PI/180 

; gegenwinkel zu alpha 
beta.f = 90*#PI/180-alpha 

; winkel des Autos 
angle.f = cara*#PI/180 

; max Lenkausschlag 
maxlenk.f = 25*#PI/180 


Repeat 
  FlipBuffers() 
  ClearScreen(0) 
  ExamineKeyboard() 
  
  ; Lenkung 
  If KeyboardPushed(#PB_Key_Left) 
    alpha - 0.05 
  ElseIf KeyboardPushed(#PB_Key_Right) 
    alpha + 0.05 
  EndIf 
  If alpha > maxlenk 
    alpha = maxlenk 
  ElseIf alpha < -maxlenk 
    alpha = -maxlenk 
  EndIf 
  
  ; beta neu berechnen: beta=90-alpha 
  beta.f = 0.5*#PI-alpha 
  
  ; Radius der Vorderachse 
  r1.f = l/Cos(beta) 
  ; Radius der Hinterachse 
  r2.f = Tan(beta)*l 
  
  ; Wendepunkt der Kurve bestimmen 
  mx.f = carx + Sin(angle)*r2 
  my.f = cary + Cos(angle)*r2 
  
  If KeyboardPushed(#PB_Key_Down) ; Bremsen
    If cars > 0 : cars - carb : EndIf
    If cars < 0 : cars = 0 : EndIf
  ElseIf KeyboardPushed(#PB_Key_Up) ; Gasgeben
    cars + carb
    If cars > carsmax : cars = carsmax : EndIf
  Else ; Rollen
    cars - carb*0.1
    If cars < 0 : cars = 0 : EndIf
  EndIf
  
    ; speed (cars) auf dem Bogen vorangehen 
    angle - cars/r1 
    If Abs(beta-#PI/2) > 0.01 
      ; neue Position des Autos bestimmen 
      carx = mx - Sin(angle)*r2 
      cary = my - Cos(angle)*r2 
    Else 
      ; neue Position des Autos bestimmen 
      carx + Cos(angle)*cars 
      cary - Sin(angle)*cars 
    EndIf 
    If alpha < 0 
      alpha + 0.02 
      If alpha > 0 
        alpha = 0 
      EndIf 
    ElseIf alpha > 0 
      alpha - 0.02 
      If alpha < 0 
        alpha = 0 
      EndIf 
    EndIf 
  
  
  Start3D() 
    ; Sprite drehen 
    RotateSprite3D(1, -angle*180/#PI, 0) 
    ; Sprite auf der Hinterachse zentrieren 
    DisplaySprite3D(1, carx-32+Cos(angle)*16, cary-32-Sin(angle)*16) 
  Stop3D() 
  
  StartDrawing(ScreenOutput()) 
    ; Hinterachse anzeigen 
    Circle(carx, cary, 3, #Red) 
    ; Drehpunkt anzeigen 
    Circle(mx, my, 3, #Green) 
    DrawingMode(4) 
    ; Auto Richtung anzeigen 
    Line(carx, cary, Cos(angle)*l, -Sin(angle)*l, #Red) 
    ; Radius Vorderachse 
    If Cos(beta) <> 0
     Circle(mx, my, l/Cos(beta), #Red) 
    EndIf
    ; Radius Hinterachse 
    If Cos(beta) <> 0 
     Circle(mx, my, Tan(beta)*l, #Blue) 
    EndIf
    ; Lenkung anzeigen 
    Line(carx+Cos(angle)*l, cary-Sin(angle)*l, Cos(angle-alpha)*10, -Sin(angle-alpha)*10, #White) 
    Line(carx+Cos(angle)*l, cary-Sin(angle)*l, Cos(angle-alpha+#PI)*10, -Sin(angle-alpha+#PI)*10, #White) 
    
    DrawingMode(1) 
    FrontColor(#White) 
    DrawText(10, 10, "Lenkeinschlag: "+Str(alpha*180/#PI)+"°", #White) 
    DrawText(10, 30, "CarAngle: "+StrF(angle*180/#PI, 2)+"°", #White) 
    DrawText(10, 50, "r2: "+StrF(r2,2), #White) 
  StopDrawing() 
  
Until KeyboardReleased(#PB_Key_Escape) 

End 
PS: Warum kommt es eigentlich manchmal zu lag ? wenn er geradeaus fährt ?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
gnasen
Beiträge: 578
Registriert: 01.08.2007 14:28
Computerausstattung: PB 4.60

Beitrag von gnasen »

Ich sage nur eins dazu, ich liebe Mathe in all seinen Facetten. Und jetzt kommt der Haken: Ich hasse Winkelsätze. Ich weiss nicht warum, aber ich mag sie einfach nicht.

Naja, zurück zum Topic:

Sehr gelungen, und die Kreise sind sehr anschaulich. 8 std ist vllt ein bisl lang, aber ich wette mit dir, das nächste mal, wenn du etwas ähnliches baust, wirst du durch die Erfahrungen extrem viel schneller sein. Von deswegen waren die 8 std garantiert nicht "verschwendet"
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

@ SG:
Nice! :allright:

@ gansen:
Recht hast du! :allright:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Ich habe das jetzt mal auf eine ganz andere Art und Weise gemacht, ohne
irgendwelche Kreise. Ist zwar ein bisschen mehr geworden, aber naja.

Code: Alles auswählen

 CompilerIf Defined(PI, #PB_Constant) = #False
  #PI      = 3.141592653589793238
CompilerEndIf
#DEG2RAD = #PI / 180

Structure V3D
  x.d
  y.d
  z.d
EndStructure

Structure Car
  pos.V3D   ;Position der Vorderachse als Koordinaten (position)
  dir.V3D   ;Richtung als Einheitsvektor (direction)
  dirr.V3D  ;Rechts als Einheitsvektor (direction right)
  diru.V3D  ;Oben als Einheitsvektor (direction up)
  ang.V3D   ;Richtung als Winkel, nur X und Y (angle)
  dist.d    ;Abstand Vorder- und Hinterachse (distance)
  w.d       ;Breite des Autos (width)
  distf.d   ;Abstand Haube von der Vorderachse (distance front)
  distb.d   ;Abstand Heck von der Hinterachse (distance back)
  ste.d     ;Lenkwinkel: 0°=gerade, 90°=rechts, 270°=links (steering)
  velo.d    ;Geschwindigkeit (velocity)
  acc.d     ;Beschleunigung (acceleration)
  fri.d     ;"Reibung" (friction)
EndStructure

Procedure Car_Draw(*car.Car)
  Protected Dim p.V3D(3) ;Ecken:   0=Vorne rechts, 1=Hinten rechts, 2=Hinten links, 3=Vorne links
  Protected Dim l.V3D(3) ;Lichter: 0=Vorne rechts, 1=Hinten rechts, 2=Hinten links, 3=Vorne links
  Protected dir.V3D, c.d, s.d
 
  With *car
    c = Cos(\ste)
    s = Sin(\ste)
    dir\x = c * \dir\x + s * \dirr\x  ;Einheitsrichtungsvektor für die Fahrtrichtung
    dir\y = c * \dir\y + s * \dirr\y
    dir\z = c * \dir\z + s * \dirr\z
   
    p(0)\x = \pos\x + \dir\x * \distf + \dirr\x * \w * 0.5
    p(0)\y = \pos\y + \dir\y * \distf + \dirr\y * \w * 0.5
    p(0)\z = \pos\z + \dir\z * \distf + \dirr\z * \w * 0.5
   
    p(1)\x = \pos\x - \dir\x * (\dist + \distb) + \dirr\x * \w * 0.5
    p(1)\y = \pos\y - \dir\y * (\dist + \distb) + \dirr\y * \w * 0.5
    p(1)\z = \pos\z - \dir\z * (\dist + \distb) + \dirr\z * \w * 0.5
   
    p(2)\x = \pos\x - \dir\x * (\dist + \distb) - \dirr\x * \w * 0.5
    p(2)\y = \pos\y - \dir\y * (\dist + \distb) - \dirr\y * \w * 0.5
    p(2)\z = \pos\z - \dir\z * (\dist + \distb) - \dirr\z * \w * 0.5
   
    p(3)\x = \pos\x + \dir\x * \distf - \dirr\x * \w * 0.5
    p(3)\y = \pos\y + \dir\y * \distf - \dirr\y * \w * 0.5
    p(3)\z = \pos\z + \dir\z * \distf - \dirr\z * \w * 0.5
   
    l(0)\x = p(0)\x - \dirr\x * 2
    l(0)\y = p(0)\y - \dirr\y * 2
    l(0)\z = p(0)\z - \dirr\z * 2
   
    l(1)\x = p(1)\x - \dirr\x * 2
    l(1)\y = p(1)\y - \dirr\y * 2
    l(1)\z = p(1)\z - \dirr\z * 2
   
    l(2)\x = p(2)\x + \dirr\x * 2
    l(2)\y = p(2)\y + \dirr\y * 2
    l(2)\z = p(2)\z + \dirr\z * 2
   
    l(3)\x = p(3)\x + \dirr\x * 2
    l(3)\y = p(3)\y + \dirr\y * 2
    l(3)\z = p(3)\z + \dirr\z * 2
   
    LineXY(p(0)\x, p(0)\y, p(1)\x, p(1)\y, $FF7F7F) ;Rahmen
    LineXY(p(1)\x, p(1)\y, p(2)\x, p(2)\y, $FF7F7F)
    LineXY(p(2)\x, p(2)\y, p(3)\x, p(3)\y, $FF7F7F)
    LineXY(p(3)\x, p(3)\y, p(0)\x, p(0)\y, $FF7F7F)
   
    LineXY(\pos\x - dir\x * 5, \pos\y - dir\y * 5, \pos\x + dir\x * 5, \pos\y + dir\y * 5, $00FF00) ;Lenkung
   
    Circle(l(0)\x, l(0)\y, 3, $FFFFFF) ;Lichter
    Circle(l(3)\x, l(3)\y, 3, $FFFFFF)
    Circle(l(1)\x, l(1)\y, 3, $7F7FFF)
    Circle(l(2)\x, l(2)\y, 3, $7F7FFF)
  EndWith
EndProcedure

Procedure Car_Steering(*car.Car, angle.d)
  *car\ste = angle
EndProcedure
Procedure Car_Dimensions(*car.Car, dist.d, distf.d, distb.d, width.d)
  *car\dist = dist
  *car\distf = distf
  *car\distb = distb
  *car\w = width
EndProcedure
Procedure Car_Velocity(*car.Car, velocity.d)
  *car\velo = velocity
EndProcedure
Procedure Car_Position(*car.Car, *Position.V3D, x.d = 0, y.d = 0, z.d = 0)
  If *Position
    *car\pos\x = *Position\x
    *car\pos\y = *Position\y
    *car\pos\z = *Position\z
  Else
    *car\pos\x = x
    *car\pos\y = y
    *car\pos\z = z
  EndIf
EndProcedure
Procedure Car_Direction(*car.Car, *angle.V3D, x.d = 0, y.d = 0)
  If *angle
    *car\ang\x = *angle\x
    *car\ang\y = *angle\y
    ;*car\ang\z = *angle\z
  Else
    *car\ang\x = x
    *car\ang\y = y
  EndIf
EndProcedure
Procedure Car_Acceleration(*car.Car, acceleration.d)
  *car\acc = acceleration
EndProcedure
Procedure Car_Friction(*car.Car, friction.d)
  *car\fri = friction
EndProcedure

Procedure Car_Calc(*car.Car)
  Protected a_1.d, a_2.d, a_3.d, a_4.d
 
  With *car
    a_1 = Sin(\ang\y)
    a_2 = Cos(\ang\x)
    a_3 = Cos(\ang\y)
    a_4 = Sin(\ang\x)
   
    \dir\x = a_2 * a_3
    \dir\y = a_4
    \dir\z = a_1 * a_2
   
    \dirr\x = a_4 * a_3
    \dirr\y = -a_2
    \dirr\z = a_1 * a_4
   
    \diru\x = - \dir\y * \dirr\z + \dir\z * \dirr\y
    \diru\y = - \dir\z * \dirr\x + \dir\x * \dirr\z
    \diru\z = - \dir\x * \dirr\y + \dir\y * \dirr\x
  EndWith
EndProcedure
Procedure Car_Move(*car.Car)
  Protected dir.V3D, c.d, s.d, diff.V3D, l.d
 
  With *car
    c = Cos(\ste)
    s = Sin(\ste)
    dir\x = c * \dir\x + s * \dirr\x  ;Einheitsrichtungsvektor für die Fahrtrichtung
    dir\y = c * \dir\y + s * \dirr\y
    dir\z = c * \dir\z + s * \dirr\z
   
    diff\x = \pos\x - \dir\x * \dist  ;Absolute Koordinaten für die Hinterachse
    diff\y = \pos\y - \dir\y * \dist
    diff\z = \pos\z - \dir\z * \dist
   
    \pos\x + dir\x * \velo  ;Koordinaten für die Vorderachse nach der Bewegung
    \pos\y + dir\y * \velo
    \pos\z + dir\z * \velo
    \velo * \fri
    \velo + \acc
   
    diff\x = \pos\x - diff\x  ;Abstandsvektor zwischen neuer Vorderachsen- und alter Hinterachsenposition
    diff\y = \pos\y - diff\y
    diff\z = \pos\z - diff\z
   
    l = 1 / Sqr(diff\x * diff\x + diff\y * diff\y + diff\z * diff\z)
   
    \dir\x = diff\x * l ;neuer Richtungsvektor
    \dir\y = diff\y * l
    \dir\z = diff\z * l
   
    \dirr\x = - \dir\y * \diru\z + \dir\z * \diru\y  ;Neuer Rechtsvektor
    \dirr\y = - \dir\z * \diru\x + \dir\x * \diru\z
    \dirr\z = - \dir\x * \diru\y + \dir\y * \diru\x
  EndWith
EndProcedure

Define width.l, height.l
width = 800
height = 600

If Not (InitSprite() And InitKeyboard())
  MessageRequester("Error", #PB_Compiler_File + ", Line " + Str(#PB_Compiler_Line)) : End
EndIf

If Not OpenWindow(0, 0, 0, width, height, "Car test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  MessageRequester("Error", #PB_Compiler_File + ", Line " + Str(#PB_Compiler_Line)) : End
EndIf

If Not OpenWindowedScreen(WindowID(0), 0, 0, width, height, 0, 0, 0)
  MessageRequester("Error", #PB_Compiler_File + ", Line " + Str(#PB_Compiler_Line)) : End
EndIf

Define Car.Car, ste.d = 0
Define maxste.d = #PI * 0.5                     ;max. Lenkausschlag (hier: 90°)
Define lrdown.l

Car_Steering(Car, ste)                          ;Lenkung auf 0° setzen
Car_Dimensions(Car, 40, 16, 16, 30)             ;Dimensionen setzen
Car_Position(Car, 0, width / 2, height / 2, 0)  ;Position setzen
Car_Direction(Car, 0, 1.5 * #PI)                ;Richtung setzen
Car_Velocity(Car, 0)                            ;Geschwindigkeit setzen
Car_Acceleration(Car, 0)                        ;Beschleunigung setzen
Car_Friction(Car, 0.97)                         ;"Reibung" setzen (wird in Car_Move() mit Gschw. multipliziert)
Car_Calc(Car)                                   ;Auto "berechnen"

Repeat
  ClearScreen(0)
  ExamineKeyboard()
 
  If KeyboardPushed(#PB_Key_Up)
    Car_Acceleration(Car, 0.2)
  ElseIf KeyboardPushed(#PB_Key_Down)
    Car_Acceleration(Car, -0.2)
  Else
    Car_Acceleration(Car, 0)
  EndIf
 
  lrdown = #False
  If KeyboardPushed(#PB_Key_Left)           ;links lenken
    ste - 1 * #DEG2RAD
    If ste < -maxste : ste = -maxste : EndIf
    lrdown = #True
  EndIf
  If KeyboardPushed(#PB_Key_Right)          ;rechts lenken
    ste + 1 * #DEG2RAD
    If ste > maxste : ste = maxste : EndIf
    lrdown = #True
  EndIf
  If lrdown = #False : ste * 0.90 : EndIf   ;falls nicht gelenkt wurde Lenkrad automatisch "zurückdrehen"
  Car_Steering(Car, ste)  ;Lenkwinkel übergeben
 
  Car_Move(Car) ;Auto bewegen (Position und Richtung neu berechnen)
  StartDrawing(ScreenOutput())
    Car_Draw(Car) ;Auto "malen"
   
    DrawText(0, 0, "Lenkwinkel: " + StrD(ste / #DEG2RAD, 3) + "°")
    DrawText(0, 16, "Geschwindigkeit: " + StrD(Car\velo, 3) + " Pixel/Loop")
    DrawText(0, 32, "Richtung (x,y,z): " + StrD(Car\dir\x, 3) + ", " + StrD(Car\dir\y, 3) + ", " + StrD(Car\dir\z, 3))
  StopDrawing()
 
  FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)

CloseScreen()
CloseWindow(0) 
Mir gefällt es so vom Fahrverhalten irgendwie besser. Habs jetzt aber auch
nur schnell dahergecodet, weil ich grad Lust hatte.

///Edit:
Hab noch schnell nen internen Fehler behoben und noch ein paar
'DrawText()'s reingehauen. :)

///Edit2: Angepasst an neuere PB-Version
sibru
Beiträge: 265
Registriert: 15.09.2004 18:11
Wohnort: hamburg

Beitrag von sibru »

gut gelungen :allright:


Warum hast Du 3 Ebenen (x,y, z) implementiert ? Soll´s langfristig ´n Flugsimulator werden ?

Gruss Siggi
Bild Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Bisher soll der Code gar nichts werden. Ich habe nur gestern Lust gehabt das mit dem
Kurvenfahren anders zu machen. Und 3D habe ich deswegen genommen, damit es
allgemeiner wird. Und viel mehr Programmieraufwand ist es auch nicht.

Man könnte sich jetzt natürlich auch nich hinsetzen und den Code so umschreiben, dass er
auch bei Heckgetriebenen Autos funktioniert. Den dieser Code ist für Frontantrieb geeignet.
Bei Heckantrieb wirkt sich der Lenkwinkel zusätzlich auf die Geschwindigkeit aus, wenn
man von der Masse des Autos absieht.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Ist ok, aber die Aussage ohne Kreise würd ich überdenken oder wozu brauchst du die Kreiszahl PI? :-)

Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Was ist das denn für eine komische Frage?

PI brauche ich nur, weil 'Sin()' und 'Cos()' in PureBasic in RAD angegeben
wird anstatt in GRAD. Und wenn es darum geht, in eine Richtung zu lenken
oder ein Objekt in eine Position zu bringen, braucht man zwangsweise 'Sin()'
und/oder 'Cos()'.

Überdenken tu ich also gar nichts. Nur weil irgendwo PI steht, brauch ich
keine Kreise.

@STARGÅTE:
Meine Version lagt übrigens nicht. Warum es bei deiner so ist, kann ich nicht
sagen. Hab den Code nur überflogen. (Nur damit du weißt, dass es nicht nur
bei dir lagt)
Antworten