/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ package org.opensourcephysics.display3d.core; import org.opensourcephysics.controls.XMLControl; /** * <p>Title: Camera</p> * <p>Description: This class provides access to the position of the camera, * its focus point and its distance to the projection screen that are used * to view the 3D scenes. The camera can also be rotated around the line * of sight (i.e. the line which conects the camera with the focus point).</p> * <p>The camera position can be set using either the desired X,Y,Z coordinates * or spherical coordinates around the focus point. This makes it * easy to rotate the scene both horizontally and vertically (around the focus).</p> * <p>Panning can be achieved by moving the focus point to one side.</p> * <p>Zooming is done increasing (positive zoom) or decreasing the distance * between the camera and the projection screen.</p> * <p> The projection screen is always normal to the line of sight and has * its origin at the intersection of this line with the screen itself.</p> * <p>The camera provides fives different modes of projecting points in space * to the screen. Two modes are truly three-dimensional. The other three are * planar modes. * * @author Francisco Esquembre * @version June 2005 * @see #setProjectionMode(int) */ public interface Camera { static public final int MODE_PLANAR_XY = 0; static public final int MODE_PLANAR_XZ = 1; static public final int MODE_PLANAR_YZ = 2; static public final int MODE_PERSPECTIVE_OFF = 3; static public final int MODE_PERSPECTIVE_ON = 4; static public final int MODE_NO_PERSPECTIVE = 10; static public final int MODE_PERSPECTIVE = 11; /** * Sets one of the projecting modes. Possible values are: * <ul> * <li>MODE_PERSPECTIVE or MODE_PERSPECTIVE_ON: 3D mode in which objects far away look smaller.</li> * <li>MODE_NO_PERSPECTIVE or MODE_PERSPECTIVE_OFF: 3D mode in which distance doesn't affect the size * of the objects</li> * <li>MODE_PLANAR_XY: 2D mode in which only the X and Y coordinates are displayed.</li> * <li>MODE_PLANAR_XZ: 2D mode in which only the X and Z coordinates are displayed.</li> * <li>MODE_PLANAR_YZ: 2D mode in which only the Y and Z coordinates are displayed.</li> * </ul> * <p>Changing the mode does not reset the camera. * @param mode int */ public void setProjectionMode(int mode); /** * Gets the projecting mode of the camera. * @return int * #see #setProjectionMode(int) */ public int getProjectionMode(); /** * Resets the camera to the default. * The camera is placed along the X direction, at a reasonable distance * from the center of the panel, which becomes the focus, and is not rotated. * The screen is also placed at a reasonable distance so that to view the * whole scene. */ public void reset(); /** * Sets the position of the camera. * @param x double * @param y double * @param z double */ public void setXYZ(double x, double y, double z); /** * Sets the position of the camera. * @param point double[] */ public void setXYZ(double[] point); /** * Returns the camera X coordinate * @return double the X coordinate of the camera position */ public double getX(); /** * Returns the camera Y coordinate * @return double the Y coordinate of the camera position */ public double getY(); /** * Returns the camera Z coordinate * @return double the Z coordinate of the camera position */ public double getZ(); /** * Sets the focus point of the camera. That it, the point in space * at which the camera is pointing. * @param x double * @param y double * @param z double */ public void setFocusXYZ(double x, double y, double z); /** * Sets the focus of the camera. * @param point double[] */ public void setFocusXYZ(double[] point); /** * Returns the focus X coordinate * @return double the X coordinate of the focus position */ public double getFocusX(); /** * Returns the focus Y coordinate * @return double the Y coordinate of the focus position */ public double getFocusY(); /** * Returns the focus Z coordinate * @return double the Z coordinate of the focus position */ public double getFocusZ(); /** * Sets the angle that the camera is rotated along the line of sight. * Default is 0. * @param angle double The angle in radians */ public void setRotation(double angle); /** * Returns the angle that the camera is rotated along the line of sight. * @return double */ public double getRotation(); /** * Sets the distance from the camera to the projecting screen. * @param distance double */ public void setDistanceToScreen(double distance); /** * Returns the distance from the camera to the projecting screen. * @return double */ public double getDistanceToScreen(); /** * Set the azimuthal (horizontal) angle of the camera position in spherical * coordinates with respect to the focus point. A value of 0 places the * camera in the XZ plane. * @param angle the desired angle in radians */ public void setAzimuth(double angle); /** * Get the horizontal angle of the camera position in spherical coordinates * with respect to the focus point. A value of 0 means the camera is in the * XZ plane. * @return double */ public double getAzimuth(); /** * Set the elevation (vertical) angle of the camera position in spherical * coordinates with respect to the focus point. A value of 0 places the * camera is in the XY plane. * @param angle the desired angle in radians in the range [-Math.PI/2,Math.PI/2] */ public void setAltitude(double angle); /** * Get the elevation (vertical) angle of the camera position in spherical * coordinates with respect to the focus point. A value of 0 means the * camera is in the XY plane. * @return double */ public double getAltitude(); /** * Set the angles of the camera position in spherical coordinates * with respect to the focus point. * @param azimuth the desired azimuthal angle in radians * @param altitude the desired altitude angle in radians in the range [-Math.PI/2,Math.PI/2] */ public void setAzimuthAndAltitude(double azimuth, double altitude); /** * Returns the transfomation used to project (x,y,z) points in space * to points of the form (a,b,distance). (a,b) are the coordinates * of the projected point in the screen coordinate system. distance * is a measure of how far the point is from the camera. Typically, * points in the plane parallel to the screen at the focus point * are at distance=1. * @return double */ public org.opensourcephysics.numerics.Transformation getTransformation(); /** * Copies its configuration from another camera * @param camera */ public void copyFrom(Camera camera); // ---------------------------------------------------- // XML loader // ---------------------------------------------------- abstract static class Loader implements org.opensourcephysics.controls.XML.ObjectLoader { abstract public Object createObject(XMLControl control); public void saveObject(XMLControl control, Object obj) { Camera camera = (Camera) obj; control.setValue("projection mode", camera.getProjectionMode()); //$NON-NLS-1$ control.setValue("x", camera.getX()); //$NON-NLS-1$ control.setValue("y", camera.getY()); //$NON-NLS-1$ control.setValue("z", camera.getZ()); //$NON-NLS-1$ control.setValue("focus x", camera.getFocusX()); //$NON-NLS-1$ control.setValue("focus y", camera.getFocusY()); //$NON-NLS-1$ control.setValue("focus z", camera.getFocusZ()); //$NON-NLS-1$ control.setValue("rotation", camera.getRotation()); //$NON-NLS-1$ control.setValue("distance to screen", camera.getDistanceToScreen()); //$NON-NLS-1$ } public Object loadObject(XMLControl control, Object obj) { Camera camera = (Camera) obj; camera.setProjectionMode(control.getInt("projection mode")); //$NON-NLS-1$ double x = control.getDouble("x"); //$NON-NLS-1$ double y = control.getDouble("y"); //$NON-NLS-1$ double z = control.getDouble("z"); //$NON-NLS-1$ camera.setXYZ(x, y, z); x = control.getDouble("focus x"); //$NON-NLS-1$ y = control.getDouble("focus y"); //$NON-NLS-1$ z = control.getDouble("focus z"); //$NON-NLS-1$ camera.setFocusXYZ(x, y, z); camera.setRotation(control.getDouble("rotation")); //$NON-NLS-1$ camera.setDistanceToScreen(control.getDouble("distance to screen")); //$NON-NLS-1$ return camera; } } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */