ID:139795
 
Code:
heightmap
proc
apply_heights(var/z,var/x,var/y,var/sz)
var/c
var/t
var/c1
var/c2
var/c3
var/c4
var/h
var/h1
var/h2
var/h3
var/h4
var/sx
var/sy
var/tx
var/ty
var/turf/T
var/s = (src.size-1)
var/ss = sz/s
var/mod = 1/ss
var/max = 0
for(c=0;c<s**2;c++)
c1 = ((round(c/s)*src.size)+c%s)+1
c2 = c1+1
c3 = c1+src.size
c4 = c3+1
h1 = src.heights[c1]
h2 = src.heights[c2]
h3 = src.heights[c3]
h4 = src.heights[c4]
sx = (c%s)*ss
sy = round(c/s)*ss
max = max(max,round(h1/8192))
for(t=0;t<ss**2;t++)
tx = t%ss
ty = round(t/ss)
h = round((h1-((((h4-h3)/ss)*tx)-(((h2-h1)/ss)*tx)*ty)+((((h3-h1)/ss)*ty)-(((h4-h2)/ss)*ty)*tx))/8192,1)
T = locate(x+sx+tx,y+sy+ty,z)
//T.icon_state = "0"
T.pixel_z = h*16
T.overlays += icon('layers.dmi',"[round(h)]")
T.layer = TURF_LAYER+h
sleep()


Problem description:

I've been playing with a fractal landscape generator... I've managed it before in 3D, I just don't have all the solvers and tools available in your standard 3D package, and algebra/trig is a subject I never was much good at... I KNOW I've missed something really basic here, but I'm trying to calculate the height on the z-axis for any given point between a quad selected from the heightmap.

For instance, given a heightmap with 2 subdivisions (5 indices, 4 quads squared) I have layered it over an area of 32 tiles, meaning 8 tiles per quad, squared.

For some reason, my calculating the height of the tile comes out all kinds of wrong, as you can see in my screenshot below.



This line is the culprit:

h = round((h1-((((h4-h3)/ss)*tx)-(((h2-h1)/ss)*tx)*ty)+((((h3-h1)/ss)*ty)-(((h4-h2)/ss)*ty)*tx))/8192,1)


I'm finding the endpoints on the x/y axis, and then calculating the slope (rise/run), and then multiplying by the scalar (tx and ty) to return the difference from the lower left hand corner.

Where'd I mess this up? This seems like such a simple problem, but I keep on running into the same snag, and that's when I get one corner to calculate properly, the other two don't.
I figured out what I was doing wrong... I was attempting to use a linear solution to a bilinear problem...

I was on the right track, just not thinking things through.

I ended up implementing a pretty simple bilinear interpolation solver:

        apply_heights(var/z,var/x,var/y,var/sz)
var/c
var/t
var/c1
var/c2
var/c3
var/c4
var/h
var/h1
var/h2
var/h3
var/h4
var/sx
var/sy
var/tx
var/ty
var/turf/T
var/s = (src.size-1)
var/ss = sz/s
var/mod = 1/ss
var/max = 0
var/xperc
var/yperc
for(c=0;c<s**2;c++)
c1 = ((round(c/s)*src.size)+c%s)+1
c2 = c1+1
c3 = c1+src.size
c4 = c3+1
h1 = src.heights[c1]
h2 = src.heights[c2]
h3 = src.heights[c3]
h4 = src.heights[c4]
sx = (c%s)*ss
sy = round(c/s)*ss
max = max(max,round(h1/8192))
for(t=0;t<ss**2;t++)
tx = t%ss
ty = round(t/ss)
xperc = tx/ss
yperc = ty/ss
if(tx>ty)
h = (1-xperc)*h1 + (xperc-yperc)*h2 + (yperc)*h4
else
h = (1-yperc)*h1 + (yperc-xperc)*h3 + (xperc)*h4
h = round(h/8192,1)
T = locate(x+sx+tx,y+sy+ty,z)
//T.icon_state = "0"
T.pixel_z = h*16
T.overlays += icon('layers.dmi',"[round(h)]")
T.layer = TURF_LAYER+h