; 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