plot_3d.lua
NAME
plot_3d
NOTES
3D plot package.
Example:
require("plot_3d")
plot = plot_3d.new(512, 512)
plot:xaxis{range = {-180, 180},
tickmarks = {-180, 60, 6}, ticklength = 1.5, tickdigit = {0, false},
label = "Longitude"}
plot:yaxis{range = {-90, 90},
tickmarks = {-90, 30, 3}, ticklength = 1.5, tickdigit = {0, false},
label = "Latitude"}
plot:zaxis{range = {0, 10},
tickmarks = {2, 2, 0}, ticklength = 1.5, tickdigit = {0, false},
label = "Z-Axis"}
plot:rotate(30, -50)
plot:scale(.7, .35, .6)
plot:translate(10, 40)
require("frame_shape")
frame = frame_shape(-180, -90, 0, 180, 90, 0)
frame:set{color = {.8, .8, .8, 1}}
plot:add(frame)
require("global_coastlines")
coast = global_coastlines("./data/gshhs_c.b", 0.1, true)
coast:set{color = {1, 1, 1, 1}}
plot:add(coast)
plot:show()
SOURCE
require("register")
local P = {}
if _REQUIREDNAME == nil then
plot_3d = P
else
_G[_REQUIREDNAME] = P
end
function P.new(width, height)
assert(width > 0)
assert(height > 0)
P.width = width
P.height = height
if width > height then
P.depth = width
else
P.depth = height
end
local render, scene, root, node, font, plot
= zeGrf.new("render", "scene", "node", "node", "font", "plot")
render:add(scene)
render:set{size = {width, height}}
scene:set{node = root, viewport = {0, 0, width, height}}
root:add(node, plot)
plot:font(font)
P.render = render
P.root = root
P.node = node
P.plot = plot
P.font = font
P.rotatez = 30
P.rotatex = -60
plot:rotate(P.rotatez, P.rotatex)
P.xscale = .5
P.yscale = .5
P.zscale = .4
plot:scale(P.xscale, P.yscale, P.zscale)
plot:set{axis = "x", offset = {0, -P.height * P.yscale / 2, -P.depth * P.zscale / 2}}
plot:set{axis = "y", offset = {-P.width * P.xscale / 2, 0, -P.depth * P.zscale / 2}}
plot:set{axis = "z", offset = {-P.width * P.xscale / 2, P.height * P.yscale / 2, 0}}
return P
end
function P.show(self)
require("towindow")
towindow(self.render, self.width, self.height)
end
function P.animate(self)
require("animate_plot")
animate_plot(self.render, self.width, self.height, self.plot, self.rotatez, self.rotatex)
end
function P.save(self, fname)
self.render:tofile(fname)
end
function P.rotate(self, rotatez, rotatex)
self.rotatez = rotatez
self.rotatex = rotatex
self.plot:rotate(self.rotatez, self.rotatex)
end
function P.scale(self, xscale, yscale, zscale)
self.xscale = xscale
self.yscale = yscale
self.zscale = zscale
self.plot:scale(self.xscale, self.yscale, self.zscale)
self.plot:set{axis = "x", offset = {0, -self.height * self.yscale / 2, -self.depth * self.zscale / 2}}
self.plot:set{axis = "y", offset = {-self.width * self.xscale / 2, 0, -self.depth * self.zscale / 2}}
self.plot:set{axis = "z", offset = {-self.width * self.xscale / 2, self.height * self.yscale / 2, 0}}
end
function P.translate(self, dx, dy)
self.root:translate(dx, dy, 0)
end
function P.add_static(self, object)
self.node:add(object)
end
function P.add(self, object, x, y, z)
if type(z) == "number" then
self.plot:add(object, x, y, z)
else
self.plot:add(object)
end
end
function P.xaxis(self, options)
options.axis = "x"
self.plot:set(options)
end
function P.yaxis(self, options)
options.axis = "y"
self.plot:set(options)
end
function P.zaxis(self, options)
options.axis = "z"
self.plot:set(options)
end
function P.fontsize(self, size)
self.plot:fontsize(size)
end
function P.right_yaxis(self)
self.plot:set{axis = "y", offset = {self.width * self.xscale / 2, 0, -self.depth * self.zscale / 2}}
end
function P.back_xaxis(self)
self.plot:set{axis = "x", offset = {0, P.height * P.yscale / 2, -self.depth * self.zscale / 2}}
end
function P.left_front_zaxis(self)
self.plot:set{axis = "z", offset = {-P.width * P.xscale / 2, -P.height * P.yscale / 2, 0}}
end
function P.right_front_zaxis(self)
self.plot:set{axis = "z", offset = {P.width * P.xscale / 2, -P.height * P.yscale / 2, 0}}
end
function P.right_back_zaxis(self)
self.plot:set{axis = "z", offset = {P.width * P.xscale / 2, P.height * P.yscale / 2, 0}}
end