/**************************************************************************** ** Eye.java - model a "viewing eye" in 3d space ** Copyright (C) 1996 Ray L. Ewbank ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program 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 program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** ** Direct any questions concerning this piece of Software to: ** ** Ray L. Ewbank ** 29-02 Arlington Road ** Woburn, MA 01801 ** ** (617) 938-7137 ** ** ewbank@gis.net **************************************************************************** ** The eye is at some position in a global cartesian coordinate system (where), ** looking in a particular direction (vz). It has a concept of up-down (vx) ** and left-right (vy). ** ** vx ** |_ vy eye at position where ** /| ** vz| vz is pointing toward the origin (0,0,0) ** z | ** | | ** | | ** |______|__y global cartesian coordinate system ** / \ | ** / \ | ** x \ | ** \ | ** \ | ** \| ** * (where.x,where.y) ** ** (vx,vy,vz) are three orthogonal unit vectors such that (vx X vy = vz), ** where X is the cross-product operation. ** ** The vx and vy names are chosen in order to preserve a right-hand coordinate ** system. Since the vz vector is "looking forward", in order to have a ** right-handed coordinate system (such that vx X vy = vz) we need to name ** them thus. ** ** However, on the projection plane, vx will correspond to the y-axis and vy ** to the x-axis. This might be confusing, but that's the way it works out. ** ** A 3d location plus two vectors (the third can always be computed via the ** cross product) is a lot to specify. To simplify setting up a viewpoint, ** let's set the eye to initially look in a direction from the location of ** the eye, toward the origin of the global coordinate system. Let's set ** vy to have no z-component. Then we can compute vx from (vy X vz). Then ** all we have to specify is a location. ** ** The constructor takes a position specification and sets up the eye as ** described above. ** ** This class has one more member function, Point3d transform(Point3d) that ** takes a Point3d in the global coordinate system, and transforms it to be ** in terms of the Eye coordinate system. A new Point3d is allocated and ** returned by this function. ** ** Please note. Points usually represent locations, and vectors directions. ** However they are both 3-tuples in 3d coordinate systems. Hence in the ** Point3d class I implement vector operations such as dot product and ** cross product. I'm sorry if this is confusing. When you see "Point3d" ** think "this can be either a point or a vector..." and hopefully the ** context will let you know which it is. ** ** Member functions to add in the future: ** rotatex(theta) rotate eye by theta about eye's current x-axis ** rotatey(theta) rotate eye by theta about eye's current y-axis ** rotatez(theta) rotate eye by theta about eye's current z-axis ** forward(length) move forward in z length units ** backward(length) move backward in z length units ** ** These are really pretty easy to add. Then you could "fly around" in 3d ** like a flight-simulator. */ class Eye { public Point3d where; public Point3d vx; public Point3d vy; public Point3d vz; public Eye(double ex, double ey, double ez) { where = new Point3d(ex,ey,ez); (vz = new Point3d(0,0,0).subtract(where)).normalize(); (vy = new Point3d(-ey,ex,0.0)).normalize(); vx = vy.crossp(vz); } Point3d transform(Point3d p) { Point3d v = p.subtract(where); return new Point3d(vx.dot(v),vy.dot(v),vz.dot(v)); } }