; docformat = 'rst'
;+
; Example of displaying a polygon using object graphics. The default data set is
; the cow provided in the IDL distribution.
;
; :Params:
; x : in, optional, type=1d array
; x-coordinates of polygon vertices
; y : in, optional, type=1d array
; y-coordinates of polygon vertices
; z : in, optional, type=1d array
; z-coordinates of polygon vertices
;
; :Keywords:
; polygons : in, optional, type=1d array
; how the vertices are connected to make a polygon
; renderer : in, optional, type=long
; set to 0 for hardware rendering, 1 for software rendering
;-
pro mg_show_polygon, x, y, z, polygons=polylist, renderer=renderer
compile_opt strictarr
; default data set is a cow
if (n_params() ne 3) then begin
; restore cow.sav
filename = filepath('cow10.sav', subdir=['examples', 'data'])
restore, filename=filename
endif
; view is the top-level object in this hierarchy
view = obj_new('IDLgrView', color=[200, 200, 200])
; the model controls the transformation matrix (rotation, translation, scaling)
model = obj_new('IDLgrModel')
view->add, model
; the polygon itself
polygon = obj_new('IDLgrPolygon', x, y, z, $ ; the vertices
polygons=polylist, $ ; how the vertices form polygons
color=[100, 80, 25], $
shading=1) ; Gouraud shading
model->add, polygon
; the lights are in a separate model so they don't rotate with the polygon
lightmodel = obj_new('IDLgrModel')
view->add, lightmodel
directionalLight = obj_new('IDLgrLight', type=2, location=[-1, 1, 1], intensity=0.7)
lightmodel->add, directionalLight
ambientLight = obj_new('IDLgrLight', type=0, intensity=0.3)
lightmodel->add, ambientLight
; The next few lines of code is the tricky part to scale the polygon
; correctly into the view volume.
polygon->getProperty, xrange=xr, yrange=yr, zrange=zr
; find the dimension the polygon has the largest range in and use that to
; scale the all the dimensions; alternatively, each dimension could have its
; own scaling function so each dimension takes up the same ammount of display
; space no matter what its data range
ranges = [[xr], [yr], [zr]]
m = max(ranges[1, *] - ranges[0, *], maxRangeRow)
; find the coordinate conversion function that will scale the given range
; into [0, 1]
cc = norm_coord(ranges[*, maxRangeRow])
; now translate it over, so it scales the given range into [-0.5, 0.5]
cc[0] -= 0.5
; tell the polygon what the coordinate conversion function is (notice all
; dimensions use the same one, i.e. isotropic scaling)
polygon->setProperty, xcoord_conv=cc, ycoord_conv=cc, zcoord_conv=cc
; create axes with the same scaling as the cow
xaxis = obj_new('IDLgrAxis', 0, range=xr, /exact, $
location=[xr[0], yr[0], zr[0]], $
xcoord_conv=cc, ycoord_conv=cc, zcoord_conv=cc, $
ticklen=0.025)
model->add, xaxis
yaxis = obj_new('IDLgrAxis', 1, range=yr, /exact, $
location=[xr[0], yr[0], zr[0]], $
xcoord_conv=cc, ycoord_conv=cc, zcoord_conv=cc, $
ticklen=0.025)
model->add, yaxis
zaxis = obj_new('IDLgrAxis', 2, range=zr, /exact, $
location=[xr[0], yr[0], zr[0]], $
xcoord_conv=cc, ycoord_conv=cc, zcoord_conv=cc, $
ticklen=0.025)
model->add, zaxis
; rotate to get a nicer original orientation
model->rotate, [1, 0, 0], 15
model->rotate, [0, 1, 0], -30
window = obj_new('IDLgrWindow', dimensions=[400, 400], renderer=renderer)
window->draw, view
obj_destroy, view
end