aUCBLogo Demos and Tests / landscape2


to landscape2 [randomvalue -1]
   
; 70033224, 459159795 or 148549210 is nice
   
allFullScreen
   
perspective
   
r=2^6      ;increase if you want to fly farer
   
maxy=200
   
sealevel=0
   
rfactor=40
   
yfactor=5
   
minside=1
   
miny=2
   
ifelse randomvalue==-1 
   
[   seedvalue=random IntMax
      
(reRandom seedvalue)
      
pr seedvalue
   
][   (reRandom randomvalue)
   
]
   
mypal=loadpalette "topograf.pal
   
hideTurtle
   setScreenColor 
1
   
PenUp
   
p=(mdarray List 2*r+1 2*r+1  -r)

   
a=(List -r geny -r)
   
b=(List -r geny  r)
   
c=(List  r geny  r)
   
d=(List  r geny -r)
   
ignore new_edge a a
   
ignore new_edge b b
   
ignore new_edge c c
   
ignore new_edge d d

   quad a b c d 
0

   
setX -r
   
setZ -
   
PenDown
   
SurfaceStart
   for 
[-r r minside]
   [   
py=p.(Int z)
      
for [-r r minside]
      [   
setPenColor mypal.(Int 1+255*(0.5+py.x/maxy))
         
if py.sealevel [py.x=sealevel]
         
setXYZ rfactor*x yfactor*py.x rfactor*z
      
]
      
SurfaceColumn
   
]
   
SurfaceEnd
   
   
peak=(max p)
   
for [-r r minside]
   
[   py=p.(Int z)
      
for [-r r minside]
      
[   if py.x==peak
         
[   (drawcross rfactor*x yfactor*peak rfactor*4)
            
x=r
            
z=r
         
]
      
]
   
]
   
repeat 50
   
[   x=(rnd-0.5)*2*r  x=int x-mod x minside
      
z=(rnd-0.5)*2*r  z=int z-mod z minside
      
drawhouse x z
   
]
   
repeat 100
   
[   x=(rnd-0.5)*2*r  x=int x-mod x minside
      
z=(rnd-0.5)*2*r  z=int z-mod z minside
      
drawtree x z
   
]
   
PenUp  home  setXYZ (p.0).0+maxy 0    downPitch 90
   
fly_around
   
notFullScreen
end

to drawhouse x z
   
if (p.z).x==sealevel [stop]
   
hsize=30
   
home
   
leftroll random 360
   
PenUp  
   
setXYZ rfactor*x yfactor*(p.z).x+hsize/rfactor*z
   
(house hsize)
   
csize=hsize*1.1
   
bk hsize
   
(pcube csize)
end

to drawtree x z
   
if (p.z).x==sealevel [stop]
   
tsize=40
   
PenUp  
   
home
   
setXYZ rfactor*x yfactor*(p.z).x rfactor*z
   
disableRoundLineEnds
   
setPenSize (list tsize/10 tsize/10)
   
PenDown
   
setPC "brown
   
enableCylinderLines
   
fd tsize/2
   
disableCylinderLines
   
PenUp
   
fd tsize/2-3
   
setPC "dark green
   
Sphere tsize/2
end

to fly_around
   
local [eye light center upvector]
   
center={0 0 0}
   
upvector={0 1 0}
   
eye=array 3
   
light=array 3
   
ang=3.6
   
flyspeed=0+1.0
   
dspeed=flyspeed/4
   
eyecenter=100
   
eyecenter2=eyecenter*2
   
   
penUp
   
eye=Array PosXYZ
   forward 
eyecenter
   center
=Array PosXYZ
   back 
eyecenter

   
print [leftrightup and down rotatesx c rollsa y changes speedESC exits]
   
dispatchMessages
   
forever
   
[   setEye eye center upvector
      
setLightPos {100 100 0}
      
redraw
      
back eyecenter2
      
if key? 
      
[   dispatchMessages
         local 
[ch]
         
ch=readChar
         
ifelse ch==char 255
         
[   ch=readCharExt
            
if ch==WXK_RIGHT [right ang]
            
if ch==WXK_LEFT  left ang]
            
if ch==WXK_UP    [   up ang]
            
if ch==WXK_DOWN  down ang]
         ][
            
if ch==char 27 [stop]
            
if ch=="a [flyspeed+=dspeed]
            
if ch=="y [flyspeed-=dspeed]
            
if ch=="x leftRoll ang]
            
if ch=="c [rightRoll ang]
         ]
      ]
      
forward flyspeed
      z
=round ZCor/rfactor
      y
=round YCor/yfactor
      x
=round XCor/rfactor
      
ifelse (abs z) <= r  and2  (abs x) <= r
      
[   if < (p.z).x+miny
         
[   setY yfactor*((p.z).x+miny)
            (
pr [Ooops!] bf gensym)
            
dispatchMessages
         
]
      ][   
if >  [setX rfactorr]
         
if < -[setX rfactor*-r]
         
if >  [setZ rfactorr]
         
if < -[setZ rfactor*-r]
      ]
      
forward eyecenter2
      
eye=Array PosXYZ
      
forward eyecenter
      
center=Array PosXYZ
      
back eyecenter
      
up 90  fd 1  
      
upvector=(Array PosXYZ)-eye
      upvector
/=Norm upvector
      
bk down 90
   
]
end

to geny
   
output maxy*rnd-maxy/2
end

to quad a b c d depth
;(show a b c d)
   
ac=a-c
   
if (sqrt (sqr ac.1)+(sqr ac.3)) < minside [stop]
   
local [m py]
   
m=c+(a-c)/2
   
m.2=m.2+(a.2-c.2)*(rnd-0.5)
   
setItem int m.1 p.(int m.3m.2

   
ignore new_edge a b
   
ignore new_edge b c
   
ignore new_edge c d
   
ignore new_edge d a

   q a b c d
   q b c d a
   q c d a b
   q d a b c
end

to a b c d
   
local [bn cn dn]
   
bn=new_edge a b
   cn
=new_edge a c
   dn
=new_edge a d
   quad  a  bn  cn  dn  depth
+1
end

to new_edge a b
   
local [m py]
   
m=b+(a-b)/2
   
py=(p.(int m.3)).(int m.1)
   
ifelse empty? py
   
[   m.2=m.2+(a.2-b.2)*(rnd-0.5)
      
setItem int m.1 p.(int m.3m.2
   
][   m.2=py
   
]
   
output m
end

to house [size 300] 
   
local 
   
[   hsize hpos hori
      
doorwitdh doorheight doorx doorstep doorpos doorori
   
]
   
horizon=1e4
   
hsize=size/2
   
wall=hsize/10
   
setLightAmbient rgb .4 .4 .4
;   perspective
   
hpos=PosXYZ
   
hori=Orientation
   
green=hsb 60 0.4 0.1
   
setPC green

   
pu   down 180  fd hsize  up 90
;   draw_plane
   
lt 180  fd hsize  rt 90  fd hsize  lr 90  rt 90
   
openpos=[]
   
openori=[]
   
pink=hsb 0 0.3 0.7
   
setpc pink
   
double [draw_front]  down 90  fd size  up 90  lr 90
   
double [draw_side]  down 90  fd size  up 90  lr 90
   
double [draw_back]  down 90  fd size  up 90  lr 90
   
double [draw_side]
   
fd hsize  down 30  bk wall  lt 90  fd wall  rt 90
   
draw_roof  
   
fd size+wall  down 120  fd size+wall  rt 90  fd size+2*wall  rt 90
   
draw_roof   
   
setpc pink
   
draw_openings
   
setOrientation hori
   
setPosXYZ hpos
;   rotateScene2
end

to double runlist
   
double? false
   
run runlist
   
down 90  fd wall  up 90
   
double? true
   
run runlist
   
down 90  bk wall  up 90
end

to add_open
   
if not double?
   
[   push "openpos posXYZ
      
push "openori Orientation
      
push "openheight height
      
push "openwidth width
   
]
end

to save_pos
   
opos=posXYZ  
   
oori=Orientation
end

to reset_pos
   
pu 
   
setPosXYZ opos  
   
setOrientation oori
end

to draw_plane
   
save_pos
      
fd horizon  rt 90  fd horizon  rt 90
   
setpc hsb 60 0.3 0.7
   
pd  PolyStart  repeat [fd horizon*2  rt 90]  PolyEnd
   
reset_pos
end

to draw_openings
   
while [not empty? openpos]
   
[   setPosXYZ pop "openpos
      
setOrientation pop "openori
      
width=pop "openwidth
      
height=pop "openheight
      
rr 90
      
pd
      
repeat 2
      
[   PolyStart  
            
fd height  rt 90  fd wall  rt 90  
            
fd height  rt 90  fd wall  rt 90
         
PolyEnd
         
pu fd height  up 90  pd
         
PolyStart  
            
fd width  rt 90  fd wall  rt 90  
            
fd width  rt 90  fd wall  rt 90
         
PolyEnd
         
pu fd width  up 90  pd
      
]
      
pu
   
]
end

to draw_front
   
TessStart
   
save_pos
   
pd fd hsize  rt 30  fd size  rt 120  fd size  rt 30  fd hsize
      
rt 90  fd size  rt 90
   
   
TessContour
   
height=size*3/8
   
width=height*1/2
   
doorx=size/4
   
doorstep=height/8
   
pu rt 90  fd doorx  lt 90  fd doorstep
   
add_open
   
pd fd height  rt 90  fd width  rt 90  
      
fd height  rt 90  fd width

   
TessContour
   
height=size*3/12
   
width=height*3/2
   
winx=size*9/16
   
winsill=height*6/8
   
reset_pos
      
rt 90  fd winx  lt 90  fd winsill
   
add_open
   
pd fd height  rt 90  fd width  rt 90  
      
fd height  rt 90  fd width

   
TessContour
   
height=size*3/12
   
width=height*3/2
   
winx=size*5/16
   
winsill=hsize+winsill
   
reset_pos
      
rt 90  fd winx  lt 90  fd winsill
   
add_open
   
pd fd height  rt 90  fd width  rt 90  
      
fd height  rt 90  fd width
   
TessEnd
   
reset_pos
end

to draw_back
   
TessStart
   
save_pos
   
pd fd hsize  rt 30  fd size  rt 120  fd size  rt 30  fd hsize
      
rt 90  fd size
   
   
TessContour
   
height=size*3/12
   
width=height*3/2
   
winx=size*1/16
   
winsill=height*6/8
   
reset_pos
      
rt 90  fd winx  lt 90  fd winsill
   
add_open
   
pd fd height  rt 90  fd width  rt 90  
      
fd height  rt 90  fd width
   
   
TessContour
   
winx=size*9/16
   
reset_pos
      
rt 90  fd winx  lt 90  fd winsill
   
add_open
   
pd fd height  rt 90  fd width  rt 90  
      
fd height  rt 90  fd width

   
TessContour
   
height=size*3/12
   
width=height*3/2
   
winx=size*5/16
   
winsill=hsize+winsill
   
reset_pos
      
rt 90  fd winx  lt 90  fd winsill
   
add_open
   
pd fd height  rt 90  fd width  rt 90  
      
fd height  rt 90  fd width
   
TessEnd
   
reset_pos
end

to draw_side
   
TessStart
   
save_pos
   
pd fd hsize  rt 90  fd size  rt 90  fd hsize  rt 90  fd size  rt 90

   
TessContour
   
height=size*3/12
   
width=height*3/2
   
winx=size*1/16
   
winsill=height*6/8
   
reset_pos
      
rt 90  fd winx  lt 90  fd winsill
   
add_open
   
pd fd height  rt 90  fd width  rt 90  
      
fd height  rt 90  fd width
   
   
TessContour
   
winx=size*9/16
   
reset_pos
      
rt 90  fd winx  lt 90  fd winsill
   
add_open
   
pd fd height  rt 90  fd width  rt 90  
      
fd height  rt 90  fd width
   
TessEnd
   
reset_pos
end

to draw_roof
   
pd
   
red=hsb 0 1 1
   
setPC red
   
PolyStart
      
repeat [fd size+wall  rt 90  fd size+2*wall  rt 90]
   
PolyEnd
   
pu
end