; docformat = 'rst' ;+ ; A graphics atom for the object graphics system representing a cube. ;- ;+ ; Recompute vertices and connectivity list from center and side length. ;- pro mggrcube::recompute compile_opt strictarr ; create a list of -1's and 1's to represent vertices x = reform(rebin([-1, 1], 2, 4, /sample), 8) y = reform(rebin([-1, 1], 4, 2, /sample), 8) z = reform(rebin([-1, 1], 8, /sample), 8) ; scale them to center and side x = x * self.side / 2.0 + self.center[0] y = y * self.side / 2.0 + self.center[1] z = z * self.side / 2.0 + self.center[2] ; make the 3 by 8 array verts = transpose([[x], [y], [z]]) ; make each face front = [4, 6, 7, 5, 4] back = [4, 3, 2, 0, 1] right = [4, 7, 3, 1, 5] left = [4, 2, 6, 4, 0] top = [4, 2, 3, 7, 6] bottom = [4, 4, 5, 1, 0] ; create the connectivity list polygons = [front, back, right, left, top, bottom] ; put the data into the polygon self->setProperty, data=verts, polygons=polygons end ;+ ; Set properties of the cube. ; ; :Keywords: ; center : in, optional, type=fltarr(3) ; center of the cube ; side : in, optional, type=float ; side length ; _extra : in, optional, type=keywords ; keywords to IDLgrPolygon::setProperty ;- pro mggrcube::setProperty, center=center, side=side, _extra=e compile_opt strictarr if (n_elements(center) gt 0) then begin self.center = center self->recompute endif if (n_elements(side) gt 0) then begin self.side = side self->recompute endif if (n_elements(e) gt 0) then begin self->IDLgrPolygon::setProperty, _strict_extra=e endif end ;+ ; Set properties of the cube. ; ; :Keywords: ; center : out, optional, type=fltarr(3) ; center of the cube ; side : out, optional, type=float ; side length ; _ref_extra : out, optional, type=keywords ; keywords to IDLgrPolygon::setProperty ;- pro mggrcube::getProperty, center=center, side=side, _ref_extra=e compile_opt strictarr if (arg_present(center)) then begin center = self.center endif if (arg_present(side)) then begin side = self.side endif if (n_elements(e) gt 0) then begin self->IDLgrPolygon::getProperty, _strict_extra=e endif end ;+ ; Free resouces. ;- pro mggrcube::cleanup compile_opt strictarr self->IDLgrPolygon::cleanup end ;+ ; Initialize. ; ; :Returns: ; 1 for succes, 0 otherwise ; ; :Keywords: ; center : in, optional, type=fltarr(3), default=fltarr(3) ; center of the cube ; side : in, optional, type=float, default=1.0 ; side length ; _extra : in, optional, type=keywords ; keywords to IDLgrPolygon::setProperty ;- function mggrcube::init, center=center, side=side, _extra=e compile_opt strictarr if (~self->IDLgrPolygon::init(_extra=e)) then return, 0B ; save center and side, use defaults if necessary self.center = n_elements(center) eq 0 ? fltarr(3) : center self.side = n_elements(side) eq 0 ? 1.0 : side ; compute vertices and connectivity self->recompute return, 1B end ;+ ; Define member variables. ; ; :Fields: ; center ; center of the cube ; side ; side length ;- pro mggrcube__define compile_opt strictarr define = { MGgrCube, inherits IDLgrPolygon, $ center: fltarr(3), $ side: 0.0 $ } end ; example of using this routine view = obj_new('IDLgrView') model = obj_new('IDLgrModel') view->add, model ncubes = 100 for c = 0L, ncubes - 1L do begin cube = obj_new('MGgrCube', $ center=randomu(seed, 3) - 0.5, $ side=0.1 * randomu(seed, 1), $ color=255. * randomu(seed, 3), $ style=fix(3 * randomu(seed, 1)), $ shading=fix(2 * randomu(seed, 1))) model->add, cube endfor light = obj_new('IDLgrLight', type=2, location=[1, 1, 1]) model->add, light alight = obj_new('IDLgrLight', type=0, intensity=0.5) model->add, alight model->rotate, [1, 0, 0], -90 model->rotate, [0, 1, 0], 30 model->rotate, [1, 0, 0], 45 win = obj_new('IDLgrWindow', dimensions=[400, 400], graphics_tree=view) win->draw end