/******************************************************************** * Functions for 3D plot * * Example: * import plot3d; plot3d(600, 600, 0, 1, .2, 0, 1, .2, 0, 1, .2); line3d([0, 1, .5], [0, 1, 0.5], [0, 0, 1]); show3d(); * ********************************************************************/ load("zegraph.dll"); __render = null; __scene = null; __plot = null; __font = null; __width = 512; __height = 512; __scale = 1.0; __x0 = null; __x1 = null; __y0 = null; __y1 = null; function plot3d(w=512, h=512, x0=-1, x1=1, dx=.5, y0=-1, y1=1, dy=.5, z0=-1, z1=1, dz=.5) { assert(w > 32, h >= 32, dx != 0, dy != 0, dz != 0); global:__x0 = x0; global:__x1 = x1; global:__y0 = y0; global:__y1 = y1; if (w > 800) global:__scale = w/800.0; G = zegraph("render", "scene", "node", "plot", "font", "light"); disable(G.light); node = G.node; G.rotatez = 20; G.rotatex = -60; global:__render = G.render; global:__scene = G.scene; global:__plot = G.plot; global:__font = G.font; global:__width = w; global:__height = h; __render.size(w, h); __render.add(__scene); __scene.viewport(0, 0, w, h); __scene.root(node); node.add(G.light, __plot); __plot.font(__font, 11*__scale); __plot.rotate(G.rotatez, G.rotatex); __plot.scale(0.5, 0.5, 0.5); __plot.xaxis(0, -1, -1); __plot.yaxis(-1, 0, -1); __plot.zaxis(-1, 1, 0); xaxis = __plot.xaxis(); xaxis.range(x0, x1); G.xaxis = xaxis; xaxis.title("X"); xaxis.tickmarks(x0, dx, 1); yaxis = __plot.yaxis(); yaxis.range(y0, y1); G.yaxis = yaxis; yaxis.title("Y"); yaxis.tickmarks(y0, dy, 1); zaxis = __plot.zaxis(); zaxis.range(z0, z1); G.zaxis = zaxis; zaxis.title("Z"); zaxis.tickmarks(z0, dz, 1); return G; } function line3d(x, y, z) { line = zegraph("line"); vert = zegraph("vertex"); line.vertex(vert); line.type("strip"); line.solid(1.5*__scale); __plot.add(line); n = size(x); for (i = 0; i < n; i++) vert.add(x[i], y[i], z[i]); return line; } function point3d(x, y, z) { point = zegraph("point"); vert = zegraph("vertex"); point.vertex(vert); point.size(5*__scale); __plot.add(point); if (isarray(x)) { n = size(x); for (i = 0; i < n; i++) vert.add(x[i], y[i], z[i]); } else { vert.add(x, y, z); } return point; } function text3d(x, y, z, str, halign=0, valign=-1) { text = zegraph("text"); text.font(__font, 10*__scale); text.string(str); size = text.size(); h = -size[0]/2; v = -size[1]/2; if (halign < 0) h = 0; if (halign > 0) h = -size[0]; if (valign < 0) v = 0; if (valign > 0) v = -size[1]; text.layout(h, v, 0, h + 1, v, 0, h, v + 1, 0); __plot.anchor(text, x, y, z); return text; } function image3d(p0, p1, p2, fname) { node = zegraph("node"); texture = zegraph("texture"); polygon = zegraph("polygon"); vertex = zegraph("vertex"); texcoord = zegraph("texcoord"); node.closed(true); node.add(texture, polygon); texture.image(fname, -1, -1, -1); polygon.type("quads"); polygon.color(1, 1, 1); polygon.vertex(vertex); polygon.texcoord(texcoord); vertex.add(p0[0], p0[1], p0[2], p1[0], p1[1], p1[2], p2[0]+p1[0]-p0[0], p2[1]+p1[1]-p0[1], p2[2]+p1[2]-p0[2], p2[0], p2[1], p2[2]); texcoord.add(0, 0, 1, 0, 1, 1, 0, 1); __plot.add(node); } function symbol3d(x, y, z, symbol) { if (isarray(x)) { n = size(x); for (i = 0; i < n; i++) __plot.anchor(symbol, x[i], y[i], z[i]); } else { __plot.anchor(symbol, x, y, 0); } } function show3d() { size = __render.size(); window(size[0], size[1], "callback"); function callback(hwnd, msg, wp, hwp, lwp, lp, hlp, llp) { if (msg == "PAINT") __render.towindow(hwnd); } } function scale3d(xscale=1, yscale=1, zscale=1) { __plot.scale(sx, sy, sz); } function move3d(dx, dy) { __plot.translate(dx, dy, 0); } function rotate3d(rx, rz) { __plot.translate(rz, rx); } function coast3d(gshhs, z=0) { x1 = __x0; x2 = __x1; if (lon1 < 0) { x1 += 180; x2 += 180; } data = matrix("double"); data.readgshhs(gshhs, "land", x1, x2, __y0, __y1); data.insert(2, z); if (lon1 < 0) { v1 = data[null,0]; idx = v1 >= 180; v2 = v1*0; v2[idx] = v1; v2 -= 360; v1[idx] = v2; data[null,0] = v1; } xyz = zegraph("vertex"); p = data.ptr(); xyz.add(p[0], p[1]); coast = zegraph("line"); coast.vertex(xyz); coast.type("lines"); coast.solid(__scale); return coast; }