/* * (C) 2004 - Geotechnical Software Services * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This code 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. */ package no.geosoft.cc.graphics; import no.geosoft.cc.geometry.Matrix4x4; /** * World-to-device transformation object. * * @author <a href="mailto:info@geosoft.no">GeoSoft</a> */ public class GTransformer { private final Matrix4x4 world2DeviceMatrix_; private final Matrix4x4 device2WorldMatrix_; /** * Create a new transformer instance based on the specified viewport * and world extent. * * @param viewport Viewport of transformer. * @param worldExtent World extent of transformer. */ GTransformer (GViewport viewport, GWorldExtent worldExtent) { world2DeviceMatrix_ = new Matrix4x4(); device2WorldMatrix_ = new Matrix4x4(); update (viewport, worldExtent); } /** * Reset this transformer instance based on a specified viewport * and world extent. * * @param viewport Viewport. * @param worldExtent World extent. */ void update (GViewport viewport, GWorldExtent worldExtent) { double[] w0 = worldExtent.get(0); double[] w1 = worldExtent.get(1); double[] w2 = worldExtent.get(2); int x0 = viewport.getX0(); int y0 = viewport.getY0(); int width = (int) Math.round (viewport.getWidth()); int height = (int) Math.round (viewport.getHeight()); world2DeviceMatrix_.setWorld2DeviceTransform (w0, w1, w2, x0, y0, width, height); device2WorldMatrix_.set (world2DeviceMatrix_); device2WorldMatrix_.invert(); } /** * Convert a world coordinate to device. * * @param wx X of world coordinate to convert * @param wy Y of world coordinate to convert. * @param wz Z of world coordinate to convert. * @return Device coordinate [x,y]. */ public int[] worldToDevice (double wx, double wy, double wz) { double[] world = {wx, wy, wz}; return worldToDevice (world); } /** * Convert a world coordinate to device. Ignore Z value. * * @param wx X of world coordinate to convert * @param wy Y of world coordinate to convert. * @return Device coordinate [x,y]. */ public int[] worldToDevice (double wx, double wy) { double[] world = {wx, wy, 0.0}; return worldToDevice (world); } /** * Convert a world coordinate to device. * * @param world World coordinate to convert [x,y,z]. * @return Device coordinate [x,y] */ public int[] worldToDevice (double world[]) { double result[] = new double[3]; result = world2DeviceMatrix_.transformPoint (world); int device[] = {(int) Math.round (result[0]), (int) Math.round (result[1])}; return device; } /** * Convert a device coordinate to world. * * @param x X of device coordinate to convert. * @param y Y of device coordinate to convert. * @return World coordinate [x,y,z]. */ public double[] deviceToWorld (int x, int y) { int[] device = {x, y}; return deviceToWorld (device); } /** * Convert a device coordinate to world. * * @param device Device coordinate [x,y]. * @return World coordinate [x,y,z]. */ public double[] deviceToWorld (int device[]) { double[] d = {device[0], device[1], 1.0}; return device2WorldMatrix_.transformPoint (d); } // TODO: Add methods for converting collection of points }