/* * 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.display2d; /*----------------------------------------------------------------------------------------* * Projector.java version 1.7 Nov 8 1996 * * Projector.java version 1.71 May 14 1997 * * * * Copyright (c) 1996 Yanto Suryono. All Rights Reserved. * * * * Permission to use, copy, and distribute this software for NON-COMMERCIAL purposes * * and without fee is hereby granted provided that this copyright notice appears in all * * copies and this software is not modified in any way * * * * Please send bug reports and/or corrections/suggestions to * * Yanto Suryono <d0771@cranesv.egg.kushiro-ct.ac.jp> * *----------------------------------------------------------------------------------------*/ import java.awt.Point; import java.awt.Rectangle; /** * The class <code>Projector</code> projects points in 3D space to 2D space. * * @author Yanto Suryono * @version 1.71, 17 May 1997 */ public final class SurfacePlotProjector { private double scale_x, scale_y, scale_z; // 3D scaling factor private double distance; // distance to object private double _2D_scale; // 2D scaling factor private double rotation, elevation; // rotation and elevation angle private double sin_rotation, cos_rotation; // sin and cos of rotation angle private double sin_elevation, cos_elevation; // sin and cos of elevation angle private int _2D_trans_x, _2D_trans_y; // 2D translation private int x1, x2, y1, y2; // projection area private int center_x, center_y; // center of projection area private int trans_x, trans_y; private double factor; private double sx_cos, sy_cos, sz_cos; private double sx_sin, sy_sin, sz_sin; private final double DEGTORAD = Math.PI/180; /** * The constructor of <code>Projector</code>. */ SurfacePlotProjector() { setScaling(1); setRotationAngle(0); setElevationAngle(0); setDistance(10); set2DScaling(1); set2DTranslation(0, 0); } /** * Sets the projection area. * * @param r the projection area */ public void setProjectionArea(Rectangle r) { x1 = r.x; x2 = x1+r.width; y1 = r.y; y2 = y1+r.height; center_x = (x1+x2)/2; center_y = (y1+y2)/2; trans_x = center_x+_2D_trans_x; trans_y = center_y+_2D_trans_y; } /** * Sets the rotation angle. * * @param angle the rotation angle in degrees */ public void setRotationAngle(double angle) { rotation = angle; sin_rotation = Math.sin(angle*DEGTORAD); cos_rotation = Math.cos(angle*DEGTORAD); sx_cos = -scale_x*cos_rotation; sx_sin = -scale_x*sin_rotation; sy_cos = -scale_y*cos_rotation; sy_sin = scale_y*sin_rotation; } /** * Gets current rotation angle. * * @return the rotation angle in degrees. */ public double getRotationAngle() { return rotation; } /** * Gets the sine of rotation angle. * * @return the sine of rotation angle */ public double getSinRotationAngle() { return sin_rotation; } /** * Gets the cosine of rotation angle. * * @return the cosine of rotation angle */ public double getCosRotationAngle() { return cos_rotation; } /** * Sets the elevation angle. * * @param angle the elevation angle in degrees */ public void setElevationAngle(double angle) { elevation = angle; sin_elevation = Math.sin(angle*DEGTORAD); cos_elevation = Math.cos(angle*DEGTORAD); sz_cos = scale_z*cos_elevation; sz_sin = scale_z*sin_elevation; } /** * Gets current elevation angle. * * @return the elevation angle in degrees. */ public double getElevationAngle() { return elevation; } /** * Gets the sine of elevation angle. * * @return the sine of elevation angle */ public double getSinElevationAngle() { return sin_elevation; } /** * Gets the cosine of elevation angle. * * @return the cosine of elevation angle */ public double getCosElevationAngle() { return cos_elevation; } /** * Sets the projector distance. * * @param new_distance the new distance */ public void setDistance(double new_distance) { distance = new_distance; factor = distance*_2D_scale; } /** * Gets the projector distance. * * @return the projector distance */ public double getDistance() { return distance; } /** * Sets the scaling factor in x direction. * * @param scaling the scaling factor */ public void setXScaling(double scaling) { scale_x = scaling; sx_cos = -scale_x*cos_rotation; sx_sin = -scale_x*sin_rotation; } /** * Gets the scaling factor in x direction. * * @return the scaling factor */ public double getXScaling() { return scale_x; } /** * Sets the scaling factor in y direction. * * @param scaling the scaling factor */ public void setYScaling(double scaling) { scale_y = scaling; sy_cos = -scale_y*cos_rotation; sy_sin = scale_y*sin_rotation; } /** * Gets the scaling factor in y direction. * * @return the scaling factor */ public double getYScaling() { return scale_y; } /** * Sets the scaling factor in z direction. * * @param scaling the scaling factor */ public void setZScaling(double scaling) { scale_z = scaling; sz_cos = scale_z*cos_elevation; sz_sin = scale_z*sin_elevation; } /** * Gets the scaling factor in z direction. * * @return the scaling factor */ public double getZScaling() { return scale_z; } /** * Sets the scaling factor in all direction. * * @param x the scaling factor in x direction * @param y the scaling factor in y direction * @param z the scaling factor in z direction */ public void setScaling(double x, double y, double z) { scale_x = x; scale_y = y; scale_z = z; sx_cos = -scale_x*cos_rotation; sx_sin = -scale_x*sin_rotation; sy_cos = -scale_y*cos_rotation; sy_sin = scale_y*sin_rotation; sz_cos = scale_z*cos_elevation; sz_sin = scale_z*sin_elevation; } /** * Sets the same scaling factor for all direction. * * @param scaling the scaling factor */ public void setScaling(double scaling) { scale_x = scale_y = scale_z = scaling; sx_cos = -scale_x*cos_rotation; sx_sin = -scale_x*sin_rotation; sy_cos = -scale_y*cos_rotation; sy_sin = scale_y*sin_rotation; sz_cos = scale_z*cos_elevation; sz_sin = scale_z*sin_elevation; } /** * Sets the 2D scaling factor. * * @param scaling the scaling factor */ public void set2DScaling(double scaling) { _2D_scale = scaling; factor = distance*_2D_scale; } /** * Gets the 2D scaling factor. * * @return the scaling factor */ public double get2DScaling() { return _2D_scale; } /** * Sets the 2D translation. * * @param x the x translation * @param y the y translation */ public void set2DTranslation(int x, int y) { _2D_trans_x = x; _2D_trans_y = y; trans_x = center_x+_2D_trans_x; trans_y = center_y+_2D_trans_y; } /** * Sets the 2D x translation. * * @param x the x translation */ public void set2D_xTranslation(int x) { _2D_trans_x = x; trans_x = center_x+_2D_trans_x; } /** * Gets the 2D x translation. * * @return the x translation */ public int get2D_xTranslation() { return _2D_trans_x; } /** * Sets the 2D y translation. * * @param y the y translation */ public void set2D_yTranslation(int y) { _2D_trans_y = y; trans_y = center_y+_2D_trans_y; } /** * Gets the 2D y translation. * * @return the y translation */ public int get2D_yTranslation() { return _2D_trans_y; } /** * Projects 3D points. * * @param x the x coordinate * @param y the y coordinate * @param z the z coordinate */ public final Point project(double x, double y, double z) { double temp; // rotates temp = x; x = x*sx_cos+y*sy_sin; y = temp*sx_sin+y*sy_cos; // elevates and projects temp = factor/(y*cos_elevation-z*sz_sin+distance); return new Point((int) (Math.round(x*temp)+trans_x), (int) (Math.round((y*sin_elevation+z*sz_cos)*-temp)+trans_y)); } } /* * 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 */