Buchempfehlung
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Umfassend, aber leicht verständlich führt dieses Buch in die Programmierung von ATMEL AVR Mikrocontrollern ein. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

fb:porticula NoPaste

Info
Info / Hilfe
Liste
Übersicht / Liste
Neu
Datei hochladen
Suche
Quellcode suchen
Download
Dateidownload

Achsenmodell die 5.

Uploader:MitgliedMuttonhead
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