December 04, 2020, 11:54:39 AM

### Author Topic: [bmx] Difference Clouds heightmap by JoshK [ 1+ years ago ]  (Read 712 times)

#### BlitzBot

• Jr. Member
•  • Posts: 1 ##### [bmx] Difference Clouds heightmap by JoshK [ 1+ years ago ]
« on: June 29, 2017, 12:28:40 AM »
Title : Difference Clouds heightmap
Author : JoshK
Posted : 1+ years ago

Description : This is an implementation of the diamond-square fractal algorithm used to make difference clouds.  A heightfield class was used for greater resolution.  If BlitzMax had a PF_I16 format  pixel map could be used.

Code :
Code: BlitzMax
1. Strict
2.
3. Type THeightField
4.
5.         Field size
6.         Field height:Short[,]
7.
8.         Function Create:THeightField(size)
9.                 Local h:THeightfield=New THeightField
10.                 Local height:Short[size,size]
11.                 h.height=height
12.                 h.size=size
13.                 Return h
14.         EndFunction
15.
16.         Method Copy:THeightField()
17.                 Local h:THeightfield=New THeightField
18.                 Local height:Short[size,size]
19.                 Local x,y
20.                 h.height=height
21.                 h.size=size
22.                 MemCopy h.height,height,size*size*2
23.                 Return h
24.         EndMethod
25.
26.         Method Blend(h:THeightfield,b#=0.5)
27.                 Local x,y
28.                 For x=0 To size-1
29.                         For y=0 To size-1
30.                                 height[x,y]=height[x,y]*b+h.height[x,y]*(1.0-b)
31.                         Next
32.                 Next
33.         EndMethod
34.
35.         Method Noise()
36.                 Local x,y
37.                 For x=0 To size-1
38.                         For y=0 To size-1
39.                                 height[x,y]=Rand(65536)
40.                         Next
41.                 Next
42.         EndMethod
43.
44.         Method Flatten(h#=0)
45.                 Local x,y
46.                 For x=0 To size-1
47.                         For y=0 To size-1
48.                                 height[x,y]=h*65536
49.                         Next
50.                 Next
51.         EndMethod
52.
53.         Method DiamondSquareFractal(blend#=0.5,featuresize#=64)
54.                 Local x,y,res
55.                 height[0,0]=Rand(0,65536)
56.                 height[size-1,0]=Rand(0,65536)
57.                 height[0,size-1]=Rand(0,65536)
58.                 height[size-1,size-1]=Rand(0,65536)
59.                 res=size
60.                 Local iteration
61.                 Local passes=1
62.                 Local gridsize=size
63.                 Repeat
64.                         iteration:+1
65.
66.                         'Diamond
67.                         For x=0 To passes-1
68.                                 For y=0 To passes-1
69.                                         DiamondFractal(x*(gridsize-1),y*(gridsize-1),res,blend,featuresize)
70.                                 Next
71.                         Next
72.
73.                         'Square
74.                         For x=0 To passes-1
75.                                 For y=0 To passes-1
76.                                         SquareFractal(x*(gridsize-1)+(res-1)/2,y*(gridsize-1),res,blend,featuresize)
77.                                         SquareFractal(x*(gridsize-1),y*(gridsize-1)+(res-1)/2,res,blend,featuresize)
78.                                         SquareFractal(x*(gridsize-1)+(res-1),y*(gridsize-1)+(res-1)/2,res,blend,featuresize)
79.                                         SquareFractal(x*(gridsize-1)+(res-1)/2,y*(gridsize-1)+(res-1),res,blend,featuresize)
80.                                 Next
81.                         Next
82.
83.                         res=(res+1)/2
84.                         passes:*2
85.                         If res=2 Exit
86.                         gridsize=(gridsize+1)/2
87.                 Forever
88.         EndMethod
89.
90.         Method DiamondFractal(x0,y0,d,blend#,featuresize#)
91.                 Local hd,x1,y1
92.                 x1=x0+d-1
93.                 y1=y0+d-1
94.                 hd=(d+1)/2
95.                 Local i,avg#
96.                 'Print x0+", "+y0+", "+x1+", "+y1
97.                 Local distblend#=Min(Float(d)/featuresize,1.0)
98.                 blend:*distblend
99.
100.                 height[x0+hd-1,y0+hd-1] = ( height[x0,y0] + height[x0,y1] + height[x1,y0] + height[x1,y1] ) / 4
101.         EndMethod
102.
103.         Method SquareFractal(x0,y0,d,blend#,featuresize#)
104.                 Local hd,x1,y1
105.                 x1=x0+d-1
106.                 y1=y0+d-1
107.                 hd=(d-1)/2
108.                 'Print x0+", "+y0+", "+x1+", "+y1
109.                 Local i=0
110.                 Local avg#=0.0
111.
112.                 If x0-hd=>0
113.                         i:+height[x0-hd,y0]
114.                         avg:+1
115.                 EndIf
116.
117.                 If x0+hd<=size-1
118.                         i:+height[x0+hd,y0]
119.                         avg:+1
120.                 EndIf
121.
122.                 If y0-hd=>0
123.                         i:+height[x0,y0-hd]
124.                         avg:+1
125.                 EndIf
126.
127.                 If y0+hd<=size-1
128.                         i:+height[x0,y0+hd]
129.                         avg:+1
130.                 EndIf
131.
132.                 Local distblend#=Min(Float(d)/featuresize,1.0)
133.                 blend:*distblend
134.                 height[x0,y0]=i/avg * (1.0 - blend) + Rand(65535) * blend
135.         EndMethod
136.
137.         Method Multiply(m#)
138.                 Local x,y
139.                 For x=0 To size-1
140.                         For y=0 To size-1
141.                                 height[x,y]:*m
142.                         Next
143.                 Next
144.         EndMethod
145.
146.         Method ToPixmap:TPixmap()
147.                 Local x,y,r
148.                 Local p:TPixmap=CreatePixmap(size,size,PF_I8)
149.                 For x=0 To size-1
150.                         For y=0 To size-1
151.                                 r=height[x,y]/65536.0*255.0
152.                                 p.WritePixel x,y,r+(r Shl 8)+(r Shl 16)
153.                         Next
154.                 Next
155.                 Return p
156.         EndMethod
157.
158.         Method FromPixmap(pixmap:TPixmap)
159.                 Local x,y,px,py
160.                 For x=0 To size-1
161.                         For y=0 To size-1
162.                                 px=Min(x,pixmap.width-1)
163.                                 py=Min(y,pixmap.height-1)
164.                                 height[x,y]=((pixmap.ReadPixel(px,py) & \$00FF0000) Shr 16)/255.0*65536
165.                         Next
166.                 Next
167.         EndMethod
168.
169. EndType
170.
171. Local h:THeightfield
172. h=THeightfield.Create(1025)
173. SeedRnd MilliSecs()
174. h.DiamondSquareFractal(1.0,256)
175.
176. SavePixmapPNG h.topixmap(),"test.png"
177. OpenURL "test.png"

jankupila(Posted 1+ years ago)

Work's fine, thanks

degac(Posted 1+ years ago)

Fine, but I don't like the 'final' size of the images (in your example 1025x1025 pixel for the pixmap),I can't understand why I got an 'error' in the following method
Code: [Select]
`Method ToPixmap:TPixmap() Local x , y , r Print "Size: "+size Local p:TPixmap=CreatePixmap(size-1,size-1,PF_I8)' I want to create a 512x512 pixel image NOT 513x513!!! For x=0 To size-1 For y=0 To size-1 r=height[x,y]/65536.0*255.0 p.WritePixel x,y,r+(r Shl 8)+(r Shl 16) Next Next Return p EndMethod`Well, this is not a proper error: if I change the pixel format in PF_RGB888 I obtain a pixmap of Size-1 x Size-1 pixels.Maybe it's a problem with my gfx drivers...

JoshK(Posted 1+ years ago)

If BRL adds PF_I16 I will fix it for you. [/i]