BlitzCoder Essentials
•
Home Page
•
About BlitzCoder
•
Contributors
•
Terms of Use
•
Email Us
Main Areas
•
BlitzCoder Chat
•
Discussions
•
Articles/Tutorials
•
Code Database
•
Link Database
•
Showcase Area
•
Worklogs
•
Competitions
Special Areas
•
Undocumented
Other Blitz Sites
•
Blitz Basic Home
•
Blitz Showcase
•
BlitzPlay Library
Forum Login
Username:
Password:
•
Register Now!
BlitzCoder Code Archives Page
Main Codes Page
"Tileable height map generator"
, by mycroft
A recursive function that generates a tileable height map using a midpoint displacement algorithm. The resulting height map has heights from 0.0 to 1.0 (floats/reals).
Code
; real-plasma.bb ; ; Blitz v.1.66 ; ; Global variables: ; ; plasma#(,) ; see function GeneratePlasma() ; ; Functions: ; ; GeneratePlasma(width%, height%, grain#, seed%) ; GeneratePlasma() generates a tilable height-map, stored in the ; plasma# array (matrix), of real z-values (or y-values if you are ; american) using a recursive random midpoint displacement ; algorithm. The heightmap contains values in the interval ; [0.0, 1.0]. ; NOTE! Standard disclaimer applies. ; Anyone is free to copy, use and modify this document as long as ; proper acknowledgment is given to the author. ; ; Author: Simon Wetterlind 13-08-2002 ; v.0.9.3 - Revised: 18-11-2002 by Simon Wetterlind ; Be warned! Me no spell good. ;--------------------------------------------------------------------- ;--------------------------------------------------------------------- ; VARIABLES ; storage of the plasma, this will be a width%-x-height% matrix Dim plasma#(0, 0) ;--------------------------------------------------------------------- ; FUNCTIONS ;--------------------------------------------------------------------- ; GeneratePlasma(width%, height%, grain#, seed%) ; ; GeneratePlasma() generates a tilable height-map, stored in the ; plasma# array, of real z-values (or y-values if you are american) ; using a recursive random midpoint displacement algorithm. All z ; belong to [0.0, 1.0]. ; ; width% and height% determines the size of the plasma (which is a ; width%-x-height% matrix) ; ; grain# is the "graininess" of the plasma, i.e. the influence of ; randomness ; ; seed% is the seudo-random number generator seed ; Function GeneratePlasma(width%, height%, grain#, seed%) ; seed seudo-random number generator SeedRnd(seed%) ; set storage array to correct size Dim plasma#(width% - 1, height% - 1) ; fill the array with -1 (illegal value) For j% = 0 To width% - 1 For i% = 0 To height% - 1 plasma#(j%, i%) = -1.0 Next Next ; to get a tileable plasma we need to generate the plasma in ; four steps x_max% = Ceil(Float(width% - 1)/2.0) ; mid-point x y_max% = Ceil(Float(height% - 1)/2.0) ; mid-point y ; the four corners (of the top-left part) must be initiatet plasma#(0, 0) = Rnd(0.0, 1.0) plasma#(x_max%, 0) = Rnd(0.0, 1.0) plasma#(0, y_max%) = Rnd(0.0, 1.0) plasma#(x_max%, y_max%) = Rnd(0.0, 1.0) ; start recursion of the top-left part of the plasma RecursePlasma(0, 0, x_max%, y_max%, grain#, 1.0) ; copy upper half of the left border to the upper half of the ; right border to make the upper part of the plasma tileable ; left-right For y% = 0 To y_max% plasma#(width% - 1, y%) = plasma#(0, y%) Next ; do the top-right part of the plasma RecursePlasma(x_max%, 0, width% - 1, y_max%, grain#, 1.0) ; copy to make the plasma tileable up-down For x% = 0 To width% - 1 plasma#(x%, height% - 1) = plasma#(x%, 0) Next ; now the bottom-right part RecursePlasma(x_max%, y_max%, width% - 1, height% - 1, grain#, 1.0) ; copy to make the lower half of the plasma tileable left- ; right For y% = (y_max% + 1) To height% - 1 plasma#(0, y%) = plasma#(width% - 1, y%) Next ; and last, the bottom-left part of the plasma RecursePlasma(0, y_max%, x_max%, height% - 1, grain#, 1.0) End Function ;--------------------------------------------------------------------- Function MidPointDisplace#(x0%, y0%, x1%, y1%, x2%, y2%, grain#, level#) r# = Rnd(-grain#, grain#)/level# ; comment the line above and remove the comment on the one below to ; get another type of mid point displacement function (and do the ; same in function RecursePlasma) ; r# = 0 r# = (plasma#(x0%, y0%) + plasma#(x2%, y2%))/2.0 + r# If r# < 0.0 Then r# = 0.0 If r# > 1.0 Then r# = 1.0 plasma#(x1%, y1%) = r# Return r# End Function ;--------------------------------------------------------------------- Function RecursePlasma(x0%, y0%, x2%, y2%, grain#, level#) ; if the part to recurse is to small, exit function ; I don't know if this is a sufficient termination condition ; for the recursion if width% and height% are very skewed ... If (x2% - x0% < 2) And (y2% - y0% < 2) Then Return ; change the calculation of level# to (possibly) achieve ; strange results level# = 2.0*level# x1% = Ceil((x0% + x2%)/2.0) y1% = Ceil((y0% + y2%)/2.0) v# = plasma#(x1%, y0%) If v# = -1.0 Then v# = MidPointDisplace#(x0%, y0%, x1%, y0%, x2%, y0%, grain#, level#) i# = v# v# = plasma#(x2%, y1%) If v# = -1.0 Then v# = MidPointDisplace#(x2%, y0%, x2%, y1%, x2%, y2%, grain#, level#) i# = i# + v# v# = plasma#(x1%, y2%) If v# = -1.0 Then v# = MidPointDisplace#(x0%, y2%, x1%, y2%, x2%, y2%, grain#, level#) i# = i# + v# v# = plasma#(x0%, y1%) If v# = -1.0 Then v# = MidPointDisplace#(x0%, y0%, x0%, y1%, x0%, y2%, grain#, level#) i# = i# + v# If plasma#(x1%, y1%) = -1.0 Then plasma#(x1%, y1%) = i#/4.0 ; comment the line above and remove the comment on the one below to ; get another type of mid point displacement function (and do the ; same in function MidPointDisplace) ; If plasma#(x1%, y1%) = -1.0 Then plasma#(x1%, y1%) = i#/4.0 + Rnd(-grain#, grain#)/level# RecursePlasma(x0%, y0%, x1%, y1%, grain#, level#) RecursePlasma(x1%, y0%, x2%, y1%, grain#, level#) RecursePlasma(x1%, y1%, x2%, y2%, grain#, level#) RecursePlasma(x0%, y1%, x1%, y2%, grain#, level#) End Function ;--------------------------------------------------------------------- ; EOF
Copyright(c) 2000-2004, BlitzCoder. All Rights Reserved.
Code software created by Krylar's Kreations