/******************************************************************** * class for 2D plot * * Example: import plot2d_class; G = new Plot2D; G.xaxis(range=[110, 180], tickmarks=[110, 10, 0]); G.yaxis(range=[10, 80], tickmarks=[10, 10, 0]); G.gshhs("data\\gshhs_l.b"); G.show(); * ********************************************************************/ load("zegraph.dll", "matrix.dll"); D2R = 0.017453292519943; class Plot2D { c_width = 600; c_height = 600; c_xmin = -1; c_xmax = 1; c_ymin = -1; c_ymax = 1; c_render = zegraph("render"); c_render.size(c_width, c_height, 5); c_scene = zegraph("scene"); c_scene.viewport(0, 0, c_width, c_height); c_render.add(c_scene); c_root = zegraph("node"); c_scene.root(c_root); c_plot = zegraph("plot"); c_root.add(c_plot); c_font = zegraph("font"); c_plot.font(c_font, 10); c_node = zegraph("node"); c_blend = zegraph("blend"); c_node.add(c_blend); c_node.closed(true); c_plot.add(c_node); c_xaxis = c_plot.xaxis(); c_yaxis = c_plot.yaxis(); xaxis(); yaxis(); /**************************************************************** * set image size ****************************************************************/ function size(width, height) { assert(width > 32, height >= 32); global:c_width = width; global:c_height = height; c_render.size(width, height, 5); c_scene.viewport(0, 0, width, height); } /*************************************************************** * add object to plot ***************************************************************/ function add(shape, transform=true, anchor=null) { if (isarray(anchor)) { c_plot.anchor(anchor[0], anchor[1], anchor[2], shape); } else if (transform) { c_plot.add(shape); } else { c_root.add(shape); } } /**************************************************************** * set font ****************************************************************/ function font(size=10, truetype="") { assert(size > 4); if (truetype != "") c_font.truetype(truetype); c_plot.font(size); } /**************************************************************** * scale image in the view ****************************************************************/ function scale(xscal, yscale) { c_plot.scale(xscale, yscale, 1); } /**************************************************************** * move plot up-down or left-right ****************************************************************/ function move(dx, dy) { c_root.translate(dx, dy, 0); } /**************************************************************** * set x-axis ****************************************************************/ function xaxis(title="X", range=[-1,1], bottom=true, tickmarks=[-1,.5,0], tickdigits=1) { assert(range[1] > range[0], tickmarks[0] >= range[0], tickmarks[1] > (range[1]-range[0])/50.0); global:c_xmin = range[0]; global:c_xmax = range[1]; axis = c_plot.xaxis(); axis.title(title); axis.range(range[0], range[1]); axis.tickmarks(tickmarks[0], tickmarks[1], tickmarks[2]); axis.tickdigits(tickdigits); if (bottom) c_plot.xaxis(0, -1, 0); else c_plot.xaxis(0, 1, 0); return axis; } /**************************************************************** * set y-axis ****************************************************************/ function yaxis(title="Y", range=[-1,1], left=true, tickmarks=[-1,.5,0], tickdigits=1) { assert(range[1] > range[0], tickmarks[0] >= range[0], tickmarks[1] > (range[1]-range[0])/50.0); global:c_ymin = range[0]; global:c_ymax = range[1]; axis = c_plot.yaxis(); axis.title(title); axis.range(range[0], range[1]); axis.tickmarks(tickmarks[0], tickmarks[1], tickmarks[2]); axis.tickdigits(tickdigits); if (left) c_plot.yaxis(-1, 0, 0); else c_plot.yaxis(1, 0, 0); return axis; } /**************************************************************** * draw a line ****************************************************************/ function line(x, y, smooth=false) { line = zegraph("line"); if (smooth) c_node.add(line); else c_plot.add(line); vert = zegraph("vertex"); line.vertex(vert); line.type("strip"); n = x.size(); if (isarray(x) && isarray(y)) { for (i = 0; i < n; i++) vert.add(x[i], y[i], 0); } else if (isuser(x) && isuser(y)) { D = matrix("double", n[2], 3); D[null,0] = x; D[null,1] = y; D[null,2] = 0; p = D.ptr(); vert.add(p[0], p[1]); } else { error("expecting array or double matrix"); } return line; } /**************************************************************** * draw a polygon ****************************************************************/ function polygon(x, y, fill=false) { poly = zegraph("polygon"); c_plot.add(poly); vert = zegraph("vertex"); poly.vertex(vert); poly.type("polygon"); if (!fill) poly.fill(-1); n = x.size(); if (isarray(x) && isarray(y)) { for (i = 0; i < n; i++) vert.add(x[i], y[i], 0); } else if (isuser(x) && isuser(y)) { D = matrix("double", n[2], 3); D[null,0] = x; D[null,1] = y; D[null,2] = 0; p = D.ptr(); vert.add(p[0], p[1]); } else { error("expecting array or double matrix"); } return poly; } /**************************************************************** * draw a frame ****************************************************************/ function frame(width=1.5) { poly = zegraph("polygon"); c_plot.add(poly); vert = zegraph("vertex"); poly.vertex(vert); poly.type("quads"); poly.width(width); poly.fill(-1); vert.add(c_xmin, c_ymin, 0, c_xmax, c_ymin, 0, c_xmax, c_ymax, 0, c_xmin, c_ymax, 0); return poly; } /**************************************************************** * draw points ****************************************************************/ function point(x, y, size=1, smooth=false) { point = zegraph("point"); if (smooth) c_node.add(point); else c_plot.add(point); vert = zegraph("vertex"); point.vertex(vert); if (size > 1) point.size(size); n = x.size(); if (isarray(x) && isarray(y)) { for (i = 0; i < n; i++) vert.add(x[i], y[i], 0); } else if (isuser(x) && isuser(y)) { D = matrix("double", n[2], 3); D[null,0] = x; D[null,1] = y; D[null,2] = 0; p = D.ptr(); vert.add(p[0], p[1]); } else { vert.add(x, y, 0); } return point; } /**************************************************************** * put symbol in plot ****************************************************************/ function symbol(x, y, symbol) { n = x.size(); if (isarray(x) && isarray(y)) { for (i = 0; i < n; i++) c_plot.anchor(symbol, x[i], y[i], 0); } else if (isuser(x) && isuser(y)) { for (i = 0; i < n; i++) c_plot.anchor(symbol, x[i], y[i], 0); } else { error("expecting array or double matrix"); } } /**************************************************************** * plot bars ****************************************************************/ function bar(x, dx, y) { poly = zegraph("polygon"); c_plot.add(poly); vert = zegraph("vertex"); poly.type("quads"); poly.vertex(vert); n = x.size(); if (isarray(x) && isarray(y)) { for (i = 0; i < n; i++) vert.add(x[i]-dx, c_ymin, 0, x[i]+dx, c_ymin, 0, x[i]+dx, y[i], 0, x[i]-dx, y[i], 0); } else if (isuser(x) && isuser(y)) { for (i = 0; i < n; i++) vert.add(x[i]-dx, c_ymin, 0, x[i]+dx, c_ymin, 0, x[i]+dx, y[i], 0, x[i]-dx, y[i], 0); } else { vert.add(x-dx, c_ymin, 0, x+dx, c_ymin, 0, x+dx, y, 0, x-dx, y, 0); } return poly; } /**************************************************************** * text layout ****************************************************************/ function text(x, y, string, size=12, halign=0, valign=-1) { text = zegraph("text"); text.font(c_font, size); text.string(string); 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); c_plot.anchor(text, x, y, 0); return text; } /**************************************************************** * draw arrow ****************************************************************/ function arrow(x, y, u, uscale, v, vscale, size=5, smooth=false) { line = zegraph("line"); if (smooth) c_node.add(line); else c_plot.add(line); vert = zegraph("vertex"); line.type("lines"); line.vertex(vert); a = c_plot.local(c_width, c_height, 0, 0, 0); c_plot.anchor(line, a[0], a[1], 0); a = c_plot.global(c_width, c_height, x, y, 0); x1 = a[0]; y1 = a[1]; a = c_plot.global(c_width, c_height, x + u*uscale, y + v*vscale, 0); x2 = a[0]; y2 = a[1]; vert.add(x1, y1, 0, x2, y2, 0); ax = size; ay = size / 3.0; a = direction(x1, y1, 0, x2, y2, 0); cosa = cos((a[1] + 180) * D2R); sina = sin((a[1] + 180) * D2R); x1 = x2 + ax * cosa - ay * sina; y1 = y2 + ax * sina + ay * cosa; vert.add(x1, y1, 0, x2, y2, 0); ay = -ay; x1 = x2 + ax * cosa - ay * sina; y1 = y2 + ax * sina + ay * cosa; vert.add(x1, y1, 0, x2, y2, 0); return line; } /**************************************************************** * put image in plot ****************************************************************/ function image(p1, p2, p3, p4, fname) { node = zegraph("node"); c_plot.add(node); tex = zegraph("texture"); poly = zegraph("polygon"); vert = zegraph("vertex"); st = zegraph("texcoord"); node.closed(true); node.add(tex, poly); tex.image(fname, -1, -1, -1); poly.type("quads"); poly.color(1, 1, 1); poly.vertex(vert); poly.texcoord(st); vert.add(p1[0], p1[1], 0, p2[0], p2[1], 0, p3[0], p3[1], 0, p4[0], p4[1], 0); st.add(0, 0, 1, 0, 1, 1, 0, 1); return node; } /**************************************************************** * plot coatlines ****************************************************************/ function gshhs(fname) { x1 = c_xmin; x2 = c_xmax; if (c_xmin < 0) { x1 += 180; x2 += 180; } D = matrix("double"); D.readgshhs(fname, "land", x1, x2, c_ymin, c_ymax); D.insert(2, 0); if (c_xmin < 0) { v1 = D[null,0]; idx = v1 >= 180; v2 = v1*0; v2[idx] = v1; v2 -= 360; v1[idx] = v2; D[null,0] = v1; } coast = zegraph("line"); c_plot.add(coast); coast.type("lines"); xyz = zegraph("vertex"); coast.vertex(xyz); p = D.ptr(); xyz.add(p[0], p[1]); return coast; } /**************************************************************** * show plot ****************************************************************/ function show() { window(c_width, c_height, "callback"); function callback(hwnd, msg, wp, hwp, lwp, lp, hlp, llp) { if (msg == "PAINT") { c_render.towindow(hwnd); } else if (msg == "SIZE") { hide(); } } } /**************************************************************** * save imaget ****************************************************************/ function save(fname) { c_render.tofile(fname); } }