001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030/** 031 * 032 */ 033package org.openimaj.vis.general; 034 035import javax.media.opengl.GL; 036import javax.media.opengl.GL2; 037import javax.media.opengl.GLAutoDrawable; 038import javax.media.opengl.fixedfunc.GLLightingFunc; 039import javax.media.opengl.fixedfunc.GLMatrixFunc; 040import javax.media.opengl.glu.GLU; 041import javax.media.opengl.glu.GLUquadric; 042 043import org.openimaj.image.colour.ColourMap; 044import org.openimaj.image.colour.RGBColour; 045import org.openimaj.vis.general.DotPlotVisualisation.ColouredDot; 046 047/** 048 * 049 * 050 * @author David Dupplaw (dpd@ecs.soton.ac.uk) 051 * @created 11 Jul 2013 052 * @version $Author$, $Revision$, $Date$ 053 */ 054public class DotPlotVisualisation3D extends XYZVisualisation3D<ColouredDot> implements ItemPlotter3D<ColouredDot> 055{ 056 /** A colour map to use */ 057 private ColourMap colourMap = ColourMap.Autumn; 058 059 /** Colour map range */ 060 private double colourMapMin = -1; 061 062 /** Colour map range */ 063 private double colourMapMax = 1; 064 065 /** 066 * 067 * @param width 068 * @param height 069 */ 070 public DotPlotVisualisation3D( final int width, final int height ) 071 { 072 super( width, height, null ); 073 this.plotter = this; 074 } 075 076 /** 077 * 078 * @param x 079 * @param y 080 * @param z 081 * @param size 082 */ 083 public void addPoint( final double x, final double y, final double z, final double size ) 084 { 085 Float[] c = RGBColour.RED; 086 if( this.colourMap != null ) 087 c = this.colourMap.apply( (float)((size-this.colourMapMin)/(this.colourMapMax-this.colourMapMin)) ); 088 this.data.add( new LocatedObject3D<ColouredDot>( x, y, z, new ColouredDot( size, c ) ) ); 089 } 090 091 @Override 092 public void renderRestarting() 093 { 094 } 095 096 @Override 097 public void plotObject( final GLAutoDrawable drawable, 098 final org.openimaj.vis.general.XYZVisualisation3D.LocatedObject3D<ColouredDot> object, 099 final AxesRenderer3D renderer ) 100 { 101 final double[] p = renderer.calculatePosition( new double[] 102 { object.x, object.y, object.z } ); 103 104 final GL2 gl = drawable.getGL().getGL2(); 105 106 gl.glPushMatrix(); 107 108 // Translate to the position of the dot 109 gl.glMatrixMode( GLMatrixFunc.GL_MODELVIEW ); 110 gl.glTranslated( p[0], p[1], p[2] ); 111 112 final double[] s = renderer.scaleDimension( 113 new double[] {object.object.size, object.object.size, object.object.size} ); 114 gl.glScaled( s[0], s[1], s[2] ); 115 116 // Create a sphere 117 if( !this.isEnableLights() ) 118 gl.glColor3f( object.object.colour[0], object.object.colour[1], object.object.colour[2] ); 119 else 120 { 121 final float[] rgba = { object.object.colour[0], object.object.colour[1], object.object.colour[2] }; 122 gl.glMaterialfv( GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, rgba, 0); 123 gl.glMaterialfv( GL.GL_FRONT, GLLightingFunc.GL_SPECULAR, rgba, 0); 124 gl.glMaterialf( GL.GL_FRONT, GLLightingFunc.GL_SHININESS, 0.05f); 125 } 126 127 final GLUquadric qobj0 = this.glu.gluNewQuadric(); 128 this.glu.gluQuadricDrawStyle( qobj0, GLU.GLU_FILL ); 129 this.glu.gluQuadricNormals( qobj0, GLU.GLU_SMOOTH ); 130 this.glu.gluSphere( qobj0, 1, 12, 12 ); 131 this.glu.gluDeleteQuadric( qobj0 ); 132 133 gl.glPopMatrix(); 134 } 135 136 @Override 137 public void init( final GLAutoDrawable drawable ) 138 { 139 super.init( drawable ); 140 141 final float eyeX = 0.5f, eyeY = 1f, eyeZ = 0f; 142 final float lookAtX = 0f, lookAtY = 0, lookAtZ = 0; 143 final float upX = 0, upY = 1, upZ = 0; 144 this.glu.gluLookAt( eyeX, eyeY, eyeZ, lookAtX, lookAtY, lookAtZ, upX, upY, upZ ); 145 146 // Instantiate the camera mover 147 this.cameraPosition = new RotatingCameraProvider( 148 eyeX, eyeY, eyeZ, 149 lookAtX, lookAtY, lookAtZ, 150 0.0004f, 0.0001f, 0.0002f, 0.75f, 0.75f, 1f ); 151 } 152 153 /** 154 * @return the colourMap 155 */ 156 public ColourMap getColourMap() 157 { 158 return this.colourMap; 159 } 160 161 /** 162 * @param colourMap the colourMap to set 163 */ 164 public void setColourMap( final ColourMap colourMap ) 165 { 166 this.colourMap = colourMap; 167 } 168 169 /** 170 * @return the colourMapRange 171 */ 172 public double getColourMapMin() 173 { 174 return this.colourMapMin; 175 } 176 177 /** 178 * @param colourMapRange the colourMapRange to set 179 */ 180 public void setColourMapMin( final double colourMapRange ) 181 { 182 this.colourMapMin = colourMapRange; 183 } 184 185 /** 186 * @return the colourMapMax 187 */ 188 public double getColourMapMax() 189 { 190 return this.colourMapMax; 191 } 192 193 /** 194 * @param colourMapMax the colourMapMax to set 195 */ 196 public void setColourMapMax( final double colourMapMax ) 197 { 198 this.colourMapMax = colourMapMax; 199 } 200 201 /** 202 * @param min 203 * @param max 204 */ 205 public void setColourMapRange( final double min, final double max ) 206 { 207 this.colourMapMin = min; 208 this.colourMapMax = max; 209 } 210 211 /** 212 * @param args 213 */ 214 public static void main( final String[] args ) 215 { 216 final DotPlotVisualisation3D dpv = new DotPlotVisualisation3D( 1000, 600 ); 217 dpv.getAxesRenderer().setAxesRanges( -1, 1, -1, 1, -1, 1 ); 218 dpv.setColourMapRange( 0, 0.1 ); 219 dpv.setEnableLights( false ); 220 221 for( int i = 0; i < 100; i++ ) 222 dpv.addPoint( (Math.random() - 0.5) * 2, (Math.random() - 0.5) * 2, 223 (Math.random() - 0.5) * 2, Math.random() / 10 ); 224 } 225}