/* * Richard A. DeVenezia * June 1, 2004 * Copyright 2004 * * Graphics adaptor for use with SAS javaobj */ package jdsgi; import java.awt.geom.AffineTransform; public class ViewportTransform { private double vllx = 0; private double vlly = 0; private double vurx = 0; private double vury = 0; private double vw = 0; private double vh = 0; private int dvx=0; private int dvy=0; private int dvw=0; private int dvh=0; private int W=0; private int H=0; private double wllx = 0; private double wlly = 0; private double wurx = 100; private double wury = 100; private double ww = wurx - wllx; private double wh = wury - wlly; private static int ASPECT_NONE = 0; private static int ASPECT_WIDTH = 1; private static int ASPECT_HEIGHT = 2; private int aspect = ASPECT_NONE; public double tx, ty, tw, th; // return values private Graphics g; // jsdgi private ViewportTransform() {} // force constructor with jdsgi ViewportTransform (Graphics g) // jsdgi { this.g = g; W = g.getWidth(); H = g.getHeight(); setViewport2Point (0,0,1,1); } void setViewport2Point (double x1, double y1, double x2, double y2) { vllx = x1; vlly = y1; vurx = x2; vury = y2; vw = vurx - vllx; vh = vury - vlly; // device coordinates of viewport dvx = (int) Math.round( vllx * W); dvy = (int) Math.round((1-vury) * H); dvw = (int) Math.round( vw * W); dvh = (int) Math.round( vh * H); computeAffineTransform(); } void setWindow2Point (double x1, double y1, double x2, double y2) { aspect = ASPECT_NONE; wllx = x1; wlly = y1; wurx = x2; wury = y2; ww = wurx - wllx; wh = wury - wlly; computeAffineTransform(); } void setWindow1PointWidth (double x1, double y1, double w) { aspect = ASPECT_WIDTH; wllx = x1; wlly = y1; wurx = x1 + w; ww = w; computeAffineTransform(); } void setWindow1PointHeight (double x1, double y1, double h) { aspect = ASPECT_HEIGHT; wllx = x1; wlly = y1; wury = y1 + h; wh = h; computeAffineTransform(); } void getViewport (double data[]) { data[0] = vllx; data[1] = vlly; data[2] = vurx; data[3] = vury; } /* void computeAspectedViewport (double x, double y, double data[]) { } */ void getWindow (double data[]) { data[0] = wllx; data[1] = wlly; data[2] = wurx; data[3] = wury; } void getClipRect (double data[]) { data[0] = dvx; data[1] = dvy; data[2] = dvw; data[3] = dvh; } private AffineTransform at; private void computeAffineTransform () { if (aspect == ASPECT_WIDTH) { wury = wlly + ww * vh / vw ; wh = wury - wlly; } else if (aspect == ASPECT_HEIGHT) { wurx = wllx + wh * vw / vh; ww = wurx - wllx; } // dvx = 0 + w * ( vllx + (WX - wllx) / (wurx - wllx) * (vurx - vllx) ) // dvy = h - h * ( vlly + (Wy - wlly) / (wury - wlly) * (vury - vlly) ) double kw = vw / ww; double kh = vh / wh; double fw = vllx - kw * wllx ; double fh = 1 - vlly + kh * wlly ; at = new AffineTransform ( kw * W , 0 , 0 , -kh * H , fw * W , fh * H ); } AffineTransform getAffineTransform () { return at; } // Map world coordinates to image buffer coordinates void computePixels (double x, double y, double w, double h) { x = ( x - wllx ) / ww ; y = ( y - wlly ) / wh ; w = w / ww ; h = h / wh ; x = vllx + x * vw ; y = vlly + y * vh ; w = w * vw ; h = h * vh ; tx = Math.round (W * x) ; ty = Math.round (H * (1-y)) ; tw = Math.round (W * w) ; th = Math.round (H * h) ; } void clip () { // presume default initial graphics transform is in effect g.setClip (dvx,dvy,dvw,dvh); } void clipOff () { // presume default initial graphics transform is in effect g.setClip (0,0,W,H); } public String toString () { return "("+wllx+","+wlly+"),("+wurx+","+wury+") -> ("+vllx+","+vlly+"),("+vurx+","+vury+")" ; } }