/* * (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.Geometry; /** * This class represent the area of the window where graphics * will be drawn. The viewport is defined by three points as * follows: * * <pre> * x0,y0 o-------o x1,y1 * | * | * | * x2,y2 o * </pre> * * A typical viewport will have y0 == y1 and x2 == x0, but the * definition makes it possible to create skewed viewports in * order to produce pseudo 3D graphics for instance. * <p> * Clients sets viewport on a scene through the * <tt>GScene.setViewport()</tt> methods. * * @see GScene#setViewport (int, int, int, int, int, int); * @see GScene#setViewport (int, int, int, int); * * @author <a href="mailto:info@geosoft.no">GeoSoft</a> */ public class GViewport { // To enhance indexing readability private static final int X = 0; private static final int Y = 1; private final int p0_[] = new int[2]; private final int p1_[] = new int[2]; private final int p2_[] = new int[2]; /** * Create an empty viewport. */ GViewport() { set (0, 0, 0, 0, 0, 0); } /** * Crete a rectangular viewport as specified. * * @param x0 X coordinate of upper left corner of viewport. * @param y0 Y coordinate of upper left corner of viewport. * @param width Width of viewport. * @param height Height of viewport. */ GViewport (int x0, int y0, int width, int height) { set (x0, y0, x0+width, y0, x0, y0+height); } /** * Create a viewport defined by three points. The points define * the viewport as follows: * * <pre> * x0,y0 o-------o x1,y1 * | * | * | * x2,y2 o * </pre> * * @param x0 X coordinate of first point. * @param y0 Y coordinate of first point. * @param x1 X coordinate of second point. * @param y1 Y coordinate of second point. * @param x2 X coordinate of third point. * @param y2 Y coordinate of third point. */ GViewport (int x0, int y0, int x1, int y1, int x2, int y2) { set (x0, y0, x1, y1, x2, y2); } /** * Set coordinates that defines the viewport. * * @param x0 X coordinate of first point. * @param y0 Y coordinate of first point. * @param x1 X coordinate of second point. * @param y1 Y coordinate of second point. * @param x2 X coordinate of third point. * @param y2 Y coordinate of third point. */ void set (int x0, int y0, int x1, int y1, int x2, int y2) { p0_[X] = x0; p0_[Y] = y0; p1_[X] = x1; p1_[Y] = y1; p2_[X] = x2; p2_[Y] = y2; } /** * Return viewport coordinate of specified index. * * @param index Index of coordinate to get. * @return Coordinate of point at index [x,y]. */ int[] get (int index) { switch (index) { case 0 : return p0_; case 1 : return p1_; case 2 : return p2_; } throw new ArrayIndexOutOfBoundsException (index); } /** * Resize this viewport a specified fraction in X and Y direction. * * @param dx Fraction to resize in X direction. * @param dy Fraction to resize in Y direction. */ void resize (double dx, double dy) { p0_[X] = (int) Math.round (p0_[X] * dx); p0_[Y] = (int) Math.round (p0_[Y] * dy); p1_[X] = (int) Math.round (p1_[X] * dx); p1_[Y] = (int) Math.round (p1_[Y] * dy); p2_[X] = (int) Math.round (p2_[X] * dx); p2_[Y] = (int) Math.round (p2_[Y] * dy); } /** * Return X coordinate of viewport point 0. * * @return X coordinate of viewport point 0. */ public int getX0() { return p0_[X]; } /** * Return Y coordinate of viewport point 0. * * @return Y coordinate of viewport point 0. */ public int getY0() { return p0_[Y]; } /** * Return X coordinate of viewport point 1. * * @return X coordinate of viewport point 1. */ public int getX1() { return p1_[X]; } /** * Return Y coordinate of viewport point 1. * * @return Y coordinate of viewport point 1. */ public int getY1() { return p1_[Y]; } /** * Return X coordinate of viewport point 2. * * @return X coordinate of viewport point 2. */ public int getX2() { return p2_[X]; } /** * Return Y coordinate of viewport point 2. * * @return Y coordinate of viewport point 2. */ public int getY2() { return p2_[Y]; } /** * Return X coordinate of viewport point 3. Point * 3 is the lower right corner of the viewport. * * @return X coordinate of viewport point 2. */ public int getX3() { return p2_[X] + p1_[X] - p0_[X]; } /** * Return Y coordinate of viewport point 3. Point * 3 is the lower right corner of the viewport. * * @return Y coordinate of viewport point 2. */ public int getY3() { return p1_[Y] + p2_[Y] - p0_[Y]; } /** * Return viewport point 0. * * @return Viewport point 0 [x,y]. */ int[] getP0() { return p0_; } /** * Return viewport point 1. * * @return Viewport point 1 [x,y]. */ int[] getP1() { return p1_; } /** * Return viewport point 2. * * @return Viewport point 2 [x,y]. */ int[] getP2() { return p2_; } /** * Return width of viewport * * @return Width of viewport. */ public double getWidth() { return Geometry.length (p0_[X], p0_[Y], p1_[X], p1_[Y]); } /** * Return height of viewport * * @return Width of viewport. */ public double getHeight() { return Geometry.length (p0_[X], p0_[Y], p2_[X], p2_[Y]); } /** * Check if this viewport is skewed. * * @return True if this viewport is skewed, false otherwise. */ boolean isSkewed() { return p0_[X] != p2_[X] || p0_[Y] != p1_[Y]; } /** * Return shear factor in X direction of this viewport. * * @return Shear factor in X direction of this viewport. */ double getShearFactorX() { return (double) (p2_[X] - p0_[X]) / (double) (p2_[Y] - p0_[Y]); } /** * Return shear factor in Y direction of this viewport. * * @return Shear factor in Y direction of this viewport. */ double getShearFactorY() { return (double) (p1_[Y] - p0_[Y]) / (double) (p1_[X] - p0_[X]); } /** * Return horizontal center of this viewport. * * @return Horizontal center of this viewport. */ public double getCenterX() { return (double) p2_[X] + (double) (p1_[X] - p0_[X]) / 2.0; } /** * Return vertical center of this viewport. * * @return Vertical center of this viewport. */ public double getCenterY() { return (double) p1_[Y] + (double) (p2_[Y] - p0_[Y]) / 2.0; } }