fb:porticula NoPaste
Achsenmodell die 5.
Uploader: | Muttonhead |
Datum/Zeit: | 16.11.2011 22:16:59 |
'Achsenmodel_05.bas
'weit entfernt von Physik und Realität
const as integer Xo=400,Yo=300
const as single pi =atn (1) * 4
const as single doublepi=pi*2
type vessel_ as vessel
type vector
x as single
y as single
end type
declare function GetDistance(b as vector, d as vector) as single
declare function GetArcus(b as vector,v as vector) as single
declare function GetVector(arcus as single) as vector
declare sub SetTractorA (v as vessel_ ptr)
'declare sub SetTractorB (v as vessel_ ptr)
declare sub SetTrailerA (v as vessel_ ptr)
'declare sub SetTrailerB (v as vessel_ ptr)
type ptinfo
used as integer
position as vector
align as single
distance as single
end type
/'
Fahrzeugbeschreibung gültig sowohl für Zugmaschinen als auch Anhänger
Typ 1 = Sattelzugmaschine
Typ 2 = Traktor
Typ 5 = Auflieger
Typ 6 = 2achsiger Anhänger
Alle zu berechnenden Punkte eines Objektes werden von einem Null-Punkt aus gesehen.
Bei 2achsigen Anhängern ist dieser Punkt die vordere Kupplung der Zuggabel bzw
bei Aufliegern der Königszapfen.
Die Lage dieses Punktes wird durch
die Anhängekupplung/Sattelkupplung des vorhergehenden Objektes definiert.
Bei Zugmaschinen/Traktoren liegt die Vorderachse IMMER auf diesem Punkt!!!
4 5
+----------+
| - - |
| | | |
@-----0------1-2
| | | |
| - - |
+----------+
3 6
Bei Erzeugung zeigen alle Objekte nach links, also ist die Ausrichtung = 180 grd = pi !!!
Punkt(0) = 1. Achse
Punkt(1) = 2. Achse
Punkt(2) = Kupplung (Sattelkupplung oder Maulanhängerkupplung)
Punkt(3 bis 6)=Definition Kollisionsfläche für dieses Objekt, bisher erstmal nur für die "Eigenkollision" gedacht
für alle Punkte ab Index[3], also Kollisionsflächen und später die Grafik, gilt folgendes:
Die Lage dieser Punkte wird durch den relativen Winkel zur Fahreugmittelachse
und der Entfernung zum Null-Punkt definiert.
Im Uhrzeigersinn linksseitig positiver Winkel
gegen Uhrzeigersinn rechtsseitig negativer Winkel.
Der Winkel wird in Bogenmaß angegeben
Beispiel:
^ Richtung des Objektes(hier 90 grd) definiert durch die Lage der Achse [1],[2]
|
3 | 4 Punkt[3] = +45grd = +Pi/4
\ | / Punkt[4] = -45grd = -Pi/4
\ | / Punkt[5] = -135grd = -Pi*3/4
\|/ Punkt[6] = +135grd = +Pi*3/4
@=0
/|\
/ 1 \
/ | \
5 2 5
'/
type vessel
prevvessel as vessel ptr
nextvessel as vessel ptr
vtype as integer
points(6) as ptinfo
alignment as single
end type
'gesamter Zug
type set
steer as single 'Lenkwinkel/ Bewegungsrichtung der ersten Achse
steermax as single 'max. Einlenkwinkel in Bogenmaß, gesetzt im Constructor
steercontrol as integer '1=Links 0=Gerade 2=Rechts
velocity as single 'Geschwindigkeit Einheiten/Sekunde im Koordinatensystem
velocontrol as integer '1=Beschleunigen 0=Ausrollen 2=Abbremsen
dircontrol as integer '1=Vorwärts -1=Rückwärts
timer_this as single 'aktuell vergangene Zeit seit timer_last
timer_last as single 'Systemzeit letzten Bewegung/Berechnung
firstvessel as vessel ptr 'erstes Objekt
lastvessel as vessel ptr 'letztes Objekt
'Hilfsvariablen
oldpoint as ptinfo
v as vector
alignA as vector
alignB as vector
t as single
distance as single
steertmp as single
vess as vessel ptr
declare constructor
declare destructor
declare function AddVessel(vtype as integer) as integer
declare sub HitchUpVessel (vl as vessel ptr)
declare sub MoveSet
declare sub Acceleration
declare sub Deceleration
declare sub ToLeft
declare sub ToRight
declare sub Foreward
declare sub Reverse
declare sub DrawVessels
end type
constructor set
timer_this=0
timer_last=0
dircontrol=1
steermax=45/360 * doublepi
end constructor
destructor set
dim as vessel ptr nv,v=firstvessel
if v then
do
nv=v->nextvessel
delete v
v=nv
loop until v=0
end if
end destructor
function set.AddVessel(vtype as integer) as integer
function=0
dim as vessel ptr tmp
dim as integer possible=0
if lastvessel=0 then 'Als erstes muß immer ein Zugfahrzeug gewählt werden
if vtype<5 then possible=1
else 'an nächster Stelle
if vtype>4 then 'nur noch Anhänger möglich
possible=1
if lastvessel->vtype=1 and vtype<>5 then possible=0'an Sattelschlepper ist nur Auflieger möglich
if lastvessel->vtype=2 and vtype<>6 then possible=0'an Traktor ist nur 2achsiger Anhänger möglich
end if
end if
if possible then
tmp= new vessel
if tmp then
tmp->vtype=vtype
select case vtype
case 1
SetTractorA (tmp)
case 2
'SetTractorB (tmp)
case 5
SetTrailerA (tmp)
case 6
'SetTrailerB (tmp)
end select
if vtype<5 then
'Verlinken
firstvessel=tmp
lastvessel=tmp
else
'Verlinken
lastvessel->nextvessel=tmp
tmp->prevvessel=lastvessel
lastvessel=tmp
'zur Anhängekupplung des Vorgängers bewegen
HitchUpVessel(lastvessel)
end if
function=1
end if
end if
end function
sub set.HitchUpVessel (vl as vessel ptr)
dim as vector v=vl->prevvessel->points(2).position'Position der Kupplung vom vorhergehenden Vessel
for i as integer=0 to ubound(vl->points)
vl->points(i).position.x=v.x + vl->points(i).position.x
vl->points(i).position.y=v.y + vl->points(i).position.y
next i
end sub
sub set.MoveSet
'Timersteuerung
if timer_last then timer_this = timer-timer_last
'Geschwindigkeit berechnen
if velocontrol=0 and velocity>0 then
velocity -=5*timer_this
if velocity<0 then velocity=0
end if
if velocontrol=1 and velocity<200 then
velocity +=15*timer_this
if velocity>200 then velocity=200
end if
if velocontrol=2 and velocity>0 then
velocity -=100*timer_this
if velocity<0 then velocity=0
end if
'Lenkeinschlag berechnen
if steercontrol=0 and steer<>0 then 'gerade
steertmp=abs(steer)
steertmp -= 1.4*timer_this
if steertmp<0 then steer=0 else steer=steertmp*sgn(steer)
end if
if steercontrol=1 and steer<>steermax then 'links
steer += .8*timer_this
if steer>steermax then steer=steermax
end if
if steercontrol=2 and steer<>-steermax then 'rechts
steer -= .8*timer_this
if steer<-steermax then steer=-steermax
end if
vess=firstvessel
do
if vess=firstvessel then
distance=velocity*timer_this 'Weg aus Geschwindigkeit und Zeit ermitteln
v=GetVector(vess->alignment + steer) 'Summe aus Richtungswinkel der 1. Achse und der Steuerungswinkel ergibt
'neue Position 1.Achse berechnen
oldpoint=vess->points(0)'alte Position 1.Achse merken
vess->points(0).position.x +=v.x*distance * dircontrol
vess->points(0).position.y +=v.y*distance * dircontrol
'neue Position 2.Achse berechnen (mit Zwischenposition)
v=GetVector(GetArcus(oldpoint.position,vess->points(1).position))
v.x=oldpoint.position.x + v.x * (vess->points(1).distance - distance)
v.y=oldpoint.position.y + v.y * (vess->points(1).distance - distance)
v=GetVector(GetArcus(vess->points(0).position,v))'Vektor v ist gleichzeitig auch die Richtung für die Kupplung
vess->points(1).position.x=vess->points(0).position.x + v.x * vess->points(1).distance
vess->points(1).position.y=vess->points(0).position.y + v.y * vess->points(1).distance
'neue Position hinter Kupplung berechnen
oldpoint=vess->points(2)'alte Position hintere Kupplung merken
vess->points(2).position.x=vess->points(0).position.x + v.x * vess->points(2).distance
vess->points(2).position.y=vess->points(0).position.y + v.y * vess->points(2).distance
'neue Ausrichtung des Vessels berechnen
vess->alignment=GetArcus(vess->points(1).position,vess->points(0).position)
'restliche Punkte berechnen(Kollision,später GFX)
for i as integer=3 to ubound(vess->points)
v=GetVector(vess->alignment + vess->points(i).align)
vess->points(i).position.x=vess->points(0).position.x + v.x * vess->points(i).distance
vess->points(i).position.y=vess->points(0).position.y + v.y * vess->points(i).distance
next i
else
'neue Position 1.Achse berechnen (mit Zwischenposition)
v=GetVector(GetArcus(oldpoint.position,vess->points(0).position))
v.x=oldpoint.position.x + v.x * (vess->points(0).distance - distance)
v.y=oldpoint.position.y + v.y * (vess->points(0).distance - distance)
v=GetVector(GetArcus(vess->prevvessel->points(2).position,v))'Vektor v kann bei einer Achse gleichzeitig auch die Richtung für die Kupplung sein
oldpoint=vess->points(0)'alte Position 1. Achse merken
vess->points(0).position.x=vess->prevvessel->points(2).position.x + v.x * vess->points(0).distance
vess->points(0).position.y=vess->prevvessel->points(2).position.y + v.y * vess->points(0).distance
if vess->points(1).used then 'wenn 2.Achse vorhanden
else 'wenn keine 2.Achse vorhanden
'neue Position hinter Kupplung berechnen
oldpoint=vess->points(2)'alte Position hintere Kupplung merken
vess->points(2).position.x=vess->prevvessel->points(2).position.x + v.x * vess->points(2).distance
vess->points(2).position.y=vess->prevvessel->points(2).position.y + v.y * vess->points(2).distance
alignA=vess->points(0).position
alignB=vess->prevvessel->points(2).position
end if
'neue Ausrichtung des Vessels berechnen
vess->alignment=GetArcus(alignA,alignB)
'restliche Punkte berechnen(Kollision,später GFX)
for i as integer=3 to ubound(vess->points)
v=GetVector(vess->alignment + vess->points(i).align)
vess->points(i).position.x=vess->prevvessel->points(2).position.x + v.x * vess->points(i).distance
vess->points(i).position.y=vess->prevvessel->points(2).position.y + v.y * vess->points(i).distance
next i
end if
vess=vess->nextvessel
loop until vess=0
timer_last=timer 'aktuelle Zeit für das nächstemal merken
steercontrol=0
velocontrol=0
end sub
sub set.Acceleration
velocontrol=1
end sub
sub set.Deceleration
velocontrol=2
end sub
sub set.ToLeft
steercontrol=1
end sub
sub set.ToRight
steercontrol=2
end sub
sub set.Foreward
if velocity=0 then dircontrol=1
end sub
sub set.Reverse
if velocity=0 then dircontrol=-1
end sub
sub set.DrawVessels
dim as vessel ptr v=firstvessel
if v then
do
if v->points(0).used then circle(Xo + v->points(0).position.x,Yo - v->points(0).position.y),3,&HFF0000
if v->points(1).used then circle(Xo + v->points(1).position.x,Yo - v->points(1).position.y),3,&HFF0000
circle(Xo + v->points(2).position.x,Yo - v->points(2).position.y),3,&H00FF00
line(Xo + v->points(3).position.x,Yo - v->points(3).position.y)-_
(Xo + v->points(4).position.x,Yo - v->points(4).position.y),&HFF7F00
line-(Xo + v->points(5).position.x,Yo - v->points(5).position.y),&HFF7F00
line-(Xo + v->points(6).position.x,Yo - v->points(6).position.y),&HFF7F00
line-(Xo + v->points(3).position.x,Yo - v->points(3).position.y),&HFF7F00
v=v->nextvessel
loop until v=0
end if
end sub
'**************************************
'**************************************
'Punktedefinition aller möglichen Fahrzeuge und Anhänger
sub SetTractorA (v as vessel ptr)
'Falls Koordinatenursprung als Vektor übergeben werden muß
dim as vector vo
vo.x=0
vo.y=0
'alle Punkte für Benutzung freigegeben
for i as integer=0 to ubound(v->points)
v->points(i).used=1
next i
'Ausrichtung nach links 180 grd
v->alignment=pi
'1. Achse
v->points(0).distance=0
v->points(0).position.x=0
v->points(1).position.y=0
v->points(0).align=0'ohne Bedeutung
'2.Achse
v->points(1).distance=35
v->points(1).position.x=v->points(1).distance
v->points(1).position.y=0
v->points(1).align=0'ohne Bedeutung
'Sattelkupplung
v->points(2).distance=30
v->points(2).position.x=v->points(2).distance
v->points(2).position.y=0
v->points(2).align=0'ohne Bedeutung
'Kollision
v->points(3).position.x=-5
v->points(3).position.y=-10
'Lage des Punktes relativ zur Richtung des Vessels definieren
v->points(3).align=v->alignment-GetArcus(vo,v->points(3).position)
v->points(3).distance=GetDistance(vo,v->points(3).position)
'Kollision
v->points(4).position.x=-5
v->points(4).position.y=10
'Lage des Punktes relativ zur Richtung des Vessels definieren
v->points(4).align=v->alignment-GetArcus(vo,v->points(4).position)
v->points(4).distance=GetDistance(vo,v->points(4).position)
'Kollision
v->points(5).position.x=10
v->points(5).position.y=10
'Lage des Punktes relativ zur Richtung des Vessels definieren
v->points(5).align=v->alignment-GetArcus(vo,v->points(5).position)
v->points(5).distance=GetDistance(vo,v->points(5).position)
'Kollision
v->points(6).position.x=10
v->points(6).position.y=-10
'Lage des Punktes relativ zur Richtung des Vessels definieren
v->points(6).align=v->alignment-GetArcus(vo,v->points(6).position)
v->points(6).distance=GetDistance(vo,v->points(6).position)
end sub
sub SetTrailerA (v as vessel ptr)
'Falls Koordinatenursprung als Vektor übergeben werden muß
dim as vector vo
vo.x=0
vo.y=0
v->points(0).used=1
v->points(1).used=0 '2. Achse nicht vorhanden
'alle Punkte für Benutzung freigegeben
for i as integer=2 to ubound(v->points)
v->points(i).used=1
next i
'Ausrichtung nach links 180 grd
v->alignment=pi
'1. Achse
v->points(0).distance=50
v->points(0).position.x=v->points(0).distance
v->points(0).position.y=0
v->points(0).align=0'ohne Bedeutung
'2.Achse nicht vorhanden
v->points(1).distance=0
v->points(1).position.x=0
v->points(1).position.y=0
v->points(1).align=0'ohne Bedeutung
'hintere Kupplung
v->points(2).distance=60
v->points(2).position.x=v->points(2).distance
v->points(2).position.y=0
v->points(2).align=0'ohne Bedeutung
'Kollision
v->points(3).position.x=-10
v->points(3).position.y=-10
'Lage des Punktes relativ zur Richtung des Vessels definieren
v->points(3).align=v->alignment-GetArcus(vo,v->points(3).position)
v->points(3).distance=GetDistance(vo,v->points(3).position)
'Kollision
v->points(4).position.x=-10
v->points(4).position.y=10
'Lage des Punktes relativ zur Richtung des Vessels definieren
v->points(4).align=v->alignment-GetArcus(vo,v->points(4).position)
v->points(4).distance=GetDistance(vo,v->points(4).position)
'Kollision
v->points(5).position.x=60
v->points(5).position.y=10
'Lage des Punktes relativ zur Richtung des Vessels definieren
v->points(5).align=v->alignment-GetArcus(vo,v->points(5).position)
v->points(5).distance=GetDistance(vo,v->points(5).position)
'Kollision
v->points(6).position.x=60
v->points(6).position.y=-10
'Lage des Punktes relativ zur Richtung des Vessels definieren
v->points(6).align=v->alignment-GetArcus(vo,v->points(6).position)
v->points(6).distance=GetDistance(vo,v->points(6).position)
end sub
'**************************************
'**************************************
'Hilfsfunktionen
'liefern Entfernung 2er Ortsvektoren nach Pythagoras
function GetDistance(b as vector, d as vector) as single
dim as single dx,dy
dx=d.x - b.x
dy=d.y - b.y
function=sqr(dx*dx + dy*dy)
end function
'liefert die globale Richtung(in Bogenmaß) eines Punktes v vom Standpunkt b aus gesehen
function GetArcus(b as vector,v as vector) as single
dim as single arcus
dim as vector d
d.x= v.x - b.x
d.y= v.y - b.y
arcus=atan2(d.y,d.x)
if sgn(arcus)=-1 then arcus= doublepi + arcus
function=arcus
end function
'liefert eine Richtung (in Bogenmaß) als Richtungsvektor
function GetVector(arcus as single) as vector
dim as vector v
if arcus>=doublepi then arcus=arcus-doublepi
if arcus<0 then arcus=doublepi+arcus
v.x=cos(arcus)
v.y=sin(arcus)
function=v
end function
'******************************************************************************
dim as set truck
truck.AddVessel(1)
truck.AddVessel(5)
screen 19,32
do
sleep 2
if multikey(&H11) then truck.Acceleration
if multikey(&H1F) then truck.Deceleration
if multikey(&H1E) then truck.ToLeft
if multikey(&H20) then truck.ToRight
if multikey(&H13) then truck.Reverse
if multikey(&H21) then truck.Foreward
truck.MoveSet
screenlock
cls
'line (0,0)-(Xo*2-1,Yo*2-1),&H000000,bf
'Koordinatensystem
'line (0,Yo)-(Xo*2-1,Yo),&H007f00
'line (Xo,0)-(Xo,Yo*2-1),&H7F0000
truck.DrawVessels
screenunlock
loop until inkey=chr(27)
end