fb:porticula NoPaste
Achsenmodell die 3.
Uploader: | Muttonhead |
Datum/Zeit: | 06.11.2011 22:17:40 |
'Einspur-Achsenmodel_03.bas
'weit entfernt von Physik und Realität
#include "fbgfx.bi"
const as integer Xo=400,Yo=300
const as single pi =atn (1) * 4
const as single doublepi=pi*2
type vector
x as single
y as single
end type
declare function GetAngle(b as vector,v as vector) as single
declare function GetVector(align as single) as vector
type axle
prevaxle as axle ptr 'Zeiger auf Vorgänger
nextaxle as axle ptr 'Zeiger auf Nachfolger
distAxle as integer 'Entfernung der Achse zur Kupplung vorn
posAxle as vector 'Position der Achse
distHitch as integer 'Entfernung der hinteren Kupplung zur Kupplung vorn
posHitch as vector 'Position der hinteren Kupplung/ hier
'Berechnungshilfe
oldpos as vector 'Puffer für alte Position
end type
type set
alignment as single 'globale Richtung des "Zugfahrzeugs"(definiert durch die Lage von 1. und 2. Achse)
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
firstaxle as axle ptr 'Zeiger auf erste Achse
lastaxle as axle ptr 'Zeiger auf letzte Achse
'Hilfsvariablen
tmp as axle ptr
axl as axle ptr
v as vector
t as single
distance as single
steertmp as single
declare function AddAxle(distA as integer=-1,distH as integer=-1,align as single=0) as integer
declare sub MoveAxles
declare sub CalcAlignment
declare sub DrawAxles
declare sub Acceleration
declare sub Deceleration
declare sub ToLeft
declare sub ToRight
declare sub Foreward
declare sub Reverse
declare constructor
declare destructor
end type
'Achsenfolge wird immer vom Koordinatenursprung erzeugt, soll heißen: 1. Achse ist immer in (0,0)
function set.AddAxle(distA as integer,distH as integer,align as single=0) as integer
tmp=new axle
if tmp then
if distH=0 then distH=distA
if lastaxle=0 then'wenn noch keine Achse, dann...
'erste Achse ignoriert alle Parameter
tmp->prevaxle=0
tmp->nextaxle=0
tmp->distAxle=0
tmp->posAxle.x=0
tmp->posAxle.y=0
tmp->distHitch=0
tmp->posHitch=tmp->posAxle'Kupplung/Aufhängepunkt für nächste Achse = Position der Achse
firstaxle=tmp 'als Erste setzen
else'ansonsten normales Erzeugen und Verlinken der nachfolgenden Achsen
'Verlinken
lastaxle->nextaxle=tmp
tmp->prevaxle=lastaxle
'Positionieren der Achse relativ zum vorhergehenden Achse
v=GetVector(align)'Richtungsvektor erzeugen, dessen Länge ist 1
'Position der vorhergehenden hinteren Kupplung + Skalarmultiplikation des Vektors mit dist...
tmp->posAxle.x=lastaxle->posHitch.x + v.x*distA
tmp->posAxle.y=lastaxle->posHitch.y + v.y*distA
tmp->posHitch.x=lastaxle->posHitch.x + v.x*distH
tmp->posHitch.y=lastaxle->posHitch.y + v.y*distH
'Entfernung merken
tmp->distAxle=distA
tmp->distHitch=distH
end if
lastaxle=tmp' erzeugte Achse als Letze definieren
function=1
end if
end function
sub set.MoveAxles
dim as axle ptr axl=firstaxle
dim as vector v
dim as single t,distance
axl=firstaxle
'Timersteuerung
if timer_last then timer_this = timer-timer_last
'Geschwindigkeit berechnen
select case velocontrol
case 0
if velocity>0 then
velocity -=5*timer_this
if velocity<0 then velocity=0
end if
case 1
if velocity<200 then
velocity +=15*timer_this
if velocity>200 then velocity=200
end if
case 2
if velocity>0 then
velocity -=100*timer_this
if velocity<0 then velocity=0
end if
end select
'Lenkeinschlag berechnen
select case steercontrol
case 0 'gerade
if steer<>0 then
steertmp=abs(steer)
steertmp -= 1.4*timer_this
if steertmp<0 then steer=0 else steer=steertmp*sgn(steer)
end if
case 1 'links
if steer<>steermax then
steer += .8*timer_this
if steer>steermax then steer=steermax
end if
case 2 'rechts
if steer<>-steermax then
steer -= .8*timer_this
if steer<-steermax then steer=-steermax
end if
end select
'Ausrichtung der 1.Achse neuberechnen
CalcAlignment
do
if axl=firstaxle then 'betrifft nur die erste Achse
distance=velocity*timer_this 'Weg aus Geschwindigkeit und Zeit ermitteln
v=GetVector(alignment + steer) 'Summe aus Richtungswinkel der 1. Achse und der Steuerungswinkel ergibt
'einen Vektor für die Bewegungsrichtung
axl->oldpos=axl->posAxle 'alte Position merken
axl->posAxle.x +=v.x*distance * dircontrol
axl->posAxle.y +=v.y*distance * dircontrol
axl->posHitch=axl->posAxle
else 'alle anderen Achsen
axl->oldpos=axl->posHitch 'alte Position merken
'Zwischenposition, zur alten Position der Vorgängerin ziehen
v=GetVector(GetAngle(axl->prevaxle->oldpos,axl->posAxle))
v.x=axl->prevaxle->oldpos.x + v.x * (axl->distAxle - distance)
v.y=axl->prevaxle->oldpos.y + v.y * (axl->distAxle - distance)
'entgültige Position zur neuen Position der Vorgängerin berechnen
v=GetVector(GetAngle(axl->prevaxle->posHitch,v))
axl->posAxle.x=axl->prevaxle->posHitch.x + v.x*axl->distAxle
axl->posAxle.y=axl->prevaxle->posHitch.y + v.y*axl->distAxle
axl->posHitch.x=axl->prevaxle->posHitch.x + v.x*axl->distHitch
axl->posHitch.y=axl->prevaxle->posHitch.y + v.y*axl->distHitch
end if
axl=axl->nextaxle
loop until axl=0
timer_last=timer 'aktuelle Zeit für das nächstemal merken
steercontrol=0
velocontrol=0
end sub
sub set.CalcAlignment
if lastaxle<>firstaxle then
alignment=GetAngle(firstaxle->nextaxle->posAxle,firstaxle->posAxle)'Ausrichtung der 1.Achse neuberechnen
end if
end sub
sub set.DrawAxles
dim as axle ptr axl=firstaxle
dim as integer c
do
if axl=firstaxle then c=&HFFFFFF else c=&HFF7F00
circle(Xo + axl->posAxle.x , Yo - axl->posAxle.y ),6,c
circle(Xo + axl->posHitch.x , Yo - axl->posHitch.y ),3,&H00FF00
if axl<>firstaxle then line(Xo + axl->prevaxle->posHitch.x , Yo - axl->prevaxle->posHitch.y )-(Xo + axl->posAxle.x , Yo - axl->posAxle.y ),&HFFFFFF
axl=axl->nextaxle
loop until axl=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
constructor set
timer_this=0
timer_last=0
dircontrol=1
steermax=45/360 * doublepi
end constructor
destructor set
dim as axle ptr naxl,axl=firstaxle
if axl then
do
naxl=axl->nextaxle
delete axl
axl=naxl
loop until axl=0
end if
end destructor
'liefert die globale Richtung(in Bogenmaß) eines Punktes v vom Standpunkt b aus gesehen
function GetAngle(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.AddAxle()
truck.AddAxle(47,30)
truck.AddAxle(87,90)
/'
'Trekker mit 2 Anhänger
'Traktor
truck.AddAxle()
truck.AddAxle(40,45)
'2 achsiger Anhänger mit Zuggabel
truck.AddAxle(20,20)'vordere Achse, "Kupplung"/Aufhängung für hintere Achse an gleicher Stelle
truck.AddAxle(50,55)'hintere Achse
'2 achsiger Anhänger mit Zuggabel
truck.AddAxle(20,20)'vordere Achse, "Kupplung"/Aufhängung für hintere Achse an gleicher Stelle
truck.AddAxle(50,55)'hintere Achse
'/
screenres Xo*2,Yo*2,32
do
sleep 1
if multikey(fb.sc_w) then truck.Acceleration
if multikey(fb.sc_s) then truck.Deceleration
if multikey(fb.sc_a) then truck.ToLeft
if multikey(fb.sc_d) then truck.ToRight
if multikey(fb.sc_r) then truck.Reverse
if multikey(fb.sc_f) then truck.Foreward
truck.MoveAxles
screenlock
cls
'Koordinatensystem
line (0,Yo)-(Xo*2-1,Yo),&H007f00
line (Xo,0)-(Xo,Yo*2-1),&H7F0000
truck.DrawAxles
screenunlock
loop until inkey=chr(27)
end