Buchempfehlung
MySQL kurz & gut
MySQL kurz & gut
Das preiswerte Taschen- buch stellt MySQL-rele- vante Inhalte systematisch und knapp dar, sodass es sich optimal zum Nach- schlagen beim Pro- grammieren eignet. [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

Versuch eines Landschaftsgenerators

Uploader:MitgliedMuttonhead
Datum/Zeit:08.03.2009 21:29:42

/'
die Darstellungsgrösse/-auflösung: resx,resy

Kamerablickrichtung wird durch das geodätische Horizontsystem definiert
Azimut(a,tmpa)  0=360   Nord
                  90    Ost
                  180   Süd
                  270   West

Höhe(h,tmph)    0    waagerecht (Horizont)
              +90    senkrecht nach oben (Zenit)
              -90    senkrecht nach unten (Nadir)

die Vektoren(vx,vy,vz) ergeben sich dann aus Azimut und Höhe

vz=sin(2*pi/360*h)
vx=sin(2*pi/360*a)*cos(2*pi/360*h)
vy=cos(2*pi/360*a)*cos(2*pi/360*h)

aktuelle Position des Strahls im Raum: rayposx,rayposy,rayposz

die Kameraposition: cx,cy,cz

der Öffnungswinkel (waagerecht) der Kamera (empfohlen 60-90 grd): cwx
der Öffnungswinkel (senkrecht) der Kamera (in Abhängigkeit von Öffnungswinkel und Auflösung): cwy

Winkelschrittweite in Abhängigkeit von Öffnungswinkel und Auflösung: astp,hstp

Strahlenlänge (eine Abbruchbedingung): rayl
maximale Strahlenlänge: maxrayl

Wasserspiegel: waterlevel

zum Höhenarray:
Grösse :xmin,xmax,ymin,ymax
vertikale Auflösung: bumplevel
Höhenarray: heightfield()
farbarray: colorfield()
Lage des Höhenarrays im Raum: fieldposx,fieldposy,fieldposz

damit lässt sich eine bestimmt Landschaft immer wieder generieren
Saatnummer: seed
'/


declare sub calcbump (xmin as integer ,xmax as integer ,ymin as integer ,ymax as integer,entry as integer)
const as double pi=3.1415926535897932

dim as single a,h,tmpa,tmph,vx,vy,vz,rayposx,rayposy,rayposz,astp,hstp
dim as integer resx,resy,cx,cy,cz,cwx,cwy,rayl,waterlevel,maxrayl,seed

'Auflösung
resx=800
resy=600

'Öffnungswinkel
cwx=60
cwy=cwx * (resy/resx)

'Winkelschrittweite für Azimut und Höhe
'im Bezug zum Öffnungswinkel und der Auflösung
astp=cwx/resx
hstp=cwy/resy

'Kameraposition
cx=300 'px nach ost
cy=-400'px nach süd
cz=300 'px nach oben

'Azimut u. Höhe (Blickrichtung der Kamera)
a=322 'nördlich(leicht westl.)
h=-20 'schräg nach unten

'maximale Strahlenlänge festlegen
'Abbruchbedingung!!!
maxrayl=1500

'Wasserstand
waterlevel=128


'Grösse(Höhe) und Lage des Höhenarrays festlegen
dim as integer xmin,xmax,ymin,ymax,fieldposx,fieldposy,fieldposz
dim shared as integer bumplevel
xmin=0
ymin=0
xmax=800
ymax=800
bumplevel=256
fieldposx=(xmax-xmin)\2*-1
fieldposy=(ymax-ymin)\2*-1
fieldposz=0
dim shared as integer heightfield(xmin to xmax , ymin to ymax)
dim shared as integer colorfield(xmin to xmax , ymin to ymax)

screen 20,32

'erzeugen der Höhenwerte
seed=1470
randomize seed
calcbump (xmin,xmax,ymin,ymax,1)

dim as integer i,k,actposx,actposy,col,exitloop

for k=0 to resy-1
  for i=0 to resx-1

    'momentanes Azimut und Höhe
    tmpa=a-(cwx\2) + i*astp
    tmph=h+(cwy\2) - k*hstp

    'Vektoren daraus ermitteln
    vz=sin(2*pi/360*tmph)
    vx=sin(2*pi/360*tmpa)*cos(2*pi/360*tmph)
    vy=cos(2*pi/360*tmpa)*cos(2*pi/360*tmph)

    'Ausgangsposition des Strahls ist die der Kamera
    rayposx=cx
    rayposy=cy
    rayposz=cz

    'Beginn der Strahlenverfolgung
    exitloop=0
    do
      'Vektoren drauf addieren
      rayposx +=vx
      rayposy +=vy
      rayposz +=vz

      'nur action wenn Strahl sich überm Höhenarray befindet
      if cint(rayposx)>=fieldposx and cint(rayposx)<fieldposx+xmax and _
      cint(rayposy)>=fieldposy and cint(rayposy)<fieldposy+ymax then
        actposx=cint(rayposx)-fieldposx
        actposy=cint(rayposy)-fieldposy
        if cint(rayposz)>waterlevel and cint(rayposz)<=heightfield(actposx,actposy) then
          col=rgb(heightfield(actposx,actposy),heightfield(actposx,actposy),heightfield(actposx,actposy))
          pset (i,k),col
          exitloop=1
        end if
      end if

      'Strahlenlänge für Abbruch ermitteln
      rayl=sqr(rayposx*rayposx +rayposy*rayposy +rayposz*rayposz)
      if rayl>=maxrayl then
        if rayposz<= waterlevel then pset (i,k),&H3344AA else pset (i,k),&H33AAFF
        exitloop=1
      end if
    loop until exitloop
  next i
next k
beep
sleep
end



'füllt ein Array rekursiv mit Höhenwerte!!!!
sub calcbump (xmin as integer ,xmax as integer ,ymin as integer ,ymax as integer,entry as integer)
    static as integer xfullrange,yfullrange
    dim as integer i,k,xrange,yrange,randomvalue
  dim as integer north,west,south,east,xmid,ymid,middle

    xrange=xmax-xmin
    yrange=ymax-ymin

    if entry=1 then
        for k=ymin to ymax
            for i=xmin to xmax
                heightfield(i,k)=-1
            next i
        next k

        heightfield(xmin,ymin)=rnd*bumplevel
        heightfield(xmin,ymax)=rnd*bumplevel
        heightfield(xmax,ymax)=rnd*bumplevel
        heightfield(xmax,ymin)=rnd*bumplevel

        xfullrange=xmax-xmin
    yfullrange=ymax-ymin
  end if

    if xrange>1 and yrange>1 then 'normales Befuellen des Arrays mit 4*Seite und 1*Mitte
    randomvalue=xrange / xfullrange * rnd * bumplevel
    north=(heightfield(xmin,ymax)+heightfield(xmax,ymax))/2 + (sgn(rnd-.5)*randomvalue)
    if north>=bumplevel then north=bumplevel-1
    if north<0 then north=0

    randomvalue=xrange / xfullrange * rnd * bumplevel
    south=(heightfield(xmin,ymin)+heightfield(xmax,ymin))/2 + (sgn(rnd-.5)*randomvalue)
    if south>=bumplevel then south=bumplevel-1
    if south<0 then south=0

    randomvalue=yrange / yfullrange * rnd * bumplevel
    west=(heightfield(xmin,ymin)+heightfield(xmin,ymax))/2 + (sgn(rnd-.5)*randomvalue)
    if west>=bumplevel then west=bumplevel-1
    if west<0 then west=0

    randomvalue=yrange / yfullrange * rnd * bumplevel
    east=(heightfield(xmax,ymin)+heightfield(xmax,ymax))/2 + (sgn(rnd-.5)*randomvalue)
    if east>=bumplevel then east=bumplevel-1
    if east<0 then east=0

    xmid=xmin+(xrange\2)
    ymid=ymin+(yrange\2)

    if heightfield(xmid,ymax)=-1 then heightfield(xmid,ymax)=north
    if heightfield(xmid,ymin)=-1 then heightfield(xmid,ymin)=south
    if heightfield(xmin,ymid)=-1 then heightfield(xmin,ymid)=west
    if heightfield(xmax,ymid)=-1 then heightfield(xmax,ymid)=east

    'heightfield(xmid,ymax)=north
    'heightfield(xmid,ymin)=south
    'heightfield(xmin,ymid)=west
    'heightfield(xmax,ymid)=east


    randomvalue=(xrange+yrange)/2 / (xfullrange+yfullrange)/2 * rnd * bumplevel
    middle=(heightfield(xmid,ymax) + heightfield(xmid,ymin) + heightfield(xmin,ymid) + heightfield(xmax,ymid))/4 + (sgn(rnd-.5)*randomvalue)
    if middle>=bumplevel then middle=bumplevel-1
    if middle<0 then middle=0

    heightfield(xmid,ymid)=middle

    calcbump(xmin,xmid,ymin,ymid,0)'south-west
    calcbump(xmid,xmax,ymin,ymid,0)'south-east
    calcbump(xmid,xmax,ymid,ymax,0)'north-east
    calcbump(xmin,xmid,ymid,ymax,0)'north-west
  end if



  if xrange>1 and yrange<2 then' nur noch Befüllen in west-east Richtung möglich
    randomvalue=xrange / xfullrange * rnd * bumplevel
    north=(heightfield(xmin,ymax)+heightfield(xmax,ymax))/2 + (sgn(rnd-.5)*randomvalue)
    if north>=bumplevel then north=bumplevel-1
    if north<0 then north=0

    randomvalue=xrange / xfullrange * rnd * bumplevel
    south=(heightfield(xmin,ymin)+heightfield(xmax,ymin))/2 + (sgn(rnd-.5)*randomvalue)
    if south>=bumplevel then south=bumplevel-1
    if south<0 then south=0

    xmid=xmin+(xrange\2)

    if heightfield(xmid,ymax)=-1 then heightfield(xmid,ymax)=north
    if heightfield(xmid,ymin)=-1 then heightfield(xmid,ymin)=south

    calcbump(xmin,xmid,ymin,ymax,0)'west
    calcbump(xmid,xmax,ymin,ymax,0)'east
  end if



  if yrange>1 and xrange<2 then' nur noch Befüllen in north-south Richtung möglich
    randomvalue=yrange / yfullrange * rnd * bumplevel
    west=(heightfield(xmin,ymin)+heightfield(xmin,ymax))/2 + (sgn(rnd-.5)*randomvalue)
    if west>=bumplevel then west=bumplevel-1
    if west<0 then west=0

    randomvalue=yrange / yfullrange * rnd * bumplevel
    east=(heightfield(xmax,ymin)+heightfield(xmax,ymax))/2 + (sgn(rnd-.5)*randomvalue)
    if east>=bumplevel then east=bumplevel-1
    if east<0 then east=0

    ymid=ymin+(yrange\2)

    if heightfield(xmin,ymid)=-1 then heightfield(xmin,ymid)=west
    if heightfield(xmax,ymid)=-1 then heightfield(xmax,ymid)=east

    calcbump(xmin,xmax,ymin,ymid,0)'south
    calcbump(xmin,xmax,ymid,ymax,0)'north
  end if
end sub