/**************************************************************************** ** Twin.java - aid transform from real 2d coordinte system to pixels and back ** 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 **************************************************************************** ** Sets up for transforming from a real 2d coordinate system to a pixel ** coordinate system and back. ** ** Set xmin,xmax,ymin,ymax of the window, and set the number of points ** in x and y, and an optionally an (x,y) point offset. ** ** The x-unit per pixel is always equal to the y-unit per pixel. ** The mid-points of (xmin,xmax) and (ymin,ymax) are made to fall ** exactly on the middle pixel. The "actual" (xmin,xmax) and (ymin,ymax) ** are adjusted accordingly to meet these criteria. ** ** The "middle" pixel is like 0 in the following scenarios: ** n = 3, -1 0 1 ** n = 4, -2 -1 0 1 ** n = 5, -2 -1 0 1 2 ** n = 6, -3 -2 -1 0 1 2 ** ... ** ** The four transform() member functions convert from real coordinates to ** pixel coordinates or back. ** ** Whenever you change anything, everything is recomputed. This is ** unfortunate with respect to efficiency, since you have to make several ** function calls to get everything set up right. But how often are you ** going to set this up anyway? :) */ import java.awt.*; class Twin { int w, h; int iofs, jofs; double xmin, xmax, ymin, ymax; double sxmin, sxmax, symin, symax; double dx, xdel, ydel; Twin() { w = h = 3; iofs=jofs=0; xmin = sxmin = -1.0; xmax = sxmax = 1.0; ymin = symin = -1.0; ymax = symax = 1.0; dx = 1.0; xdel = 2.0; ydel = 2.0; } void scale(double scalefactor) { double xmid = (sxmin + sxmax)/2.0; double ymid = (symin + symax)/2.0; double txdel = 0.5*(sxmax-sxmin)*scalefactor; double tydel = 0.5*(symax-symin)*scalefactor; sxmin = xmid-txdel; sxmax = xmid+txdel; symin = ymid-tydel; symax = ymid+tydel; adjustParameters(); } void setDimension(int inw, int inh) { w=inw; h=inh; adjustParameters(); } void setDimension(Dimension in) { setDimension(in.width,in.height); } void setOffset(int inx, int iny) { iofs = inx; jofs = iny; } void setOffset(Point in) { setOffset(in.x,in.y); } boolean isIn(double x, double y) { return (x >= xmin && x <= xmax && y >= ymin && y <= ymax); } boolean isIn(Point2d p) { return isIn(p.x,p.y); } void adjustDx() { double xmid = (sxmin+sxmax)/2.0; int imid = w>>1; xmin = xmid - imid*dx; xmax = xmid + (w-imid-1)*dx; double ymid = (symin+symax)/2.0; int jmid = h>>1; ymin = ymid - jmid*dx; ymax = ymid + (h-jmid-1)*dx; } void adjustParameters() { xdel = sxmax-sxmin; ydel = symax-symin; if (xdel/w > ydel/h) dx = xdel/(w-1); else dx = ydel/(h-1); adjustDx(); xdel = xmax-xmin; ydel = ymax-ymin; } void setWindow(double x0,double y0, double x1, double y1) { sxmin = x0; symin = y0; sxmax = x1; symax = y1; adjustParameters(); } Point transform(double x, double y) { return new Point(iofs+ (int)((x-xmin)/dx+0.5), jofs+(h-(int)((y-ymin)/dx+0.5))); } Point transform(Point2d p) { return transform(p.x,p.y); } Point2d transform(int x, int y) { return new Point2d((x-iofs)*dx+xmin,(h-(y-jofs))*dx+ymin); } Point2d transform(Point in) { return transform(in.x,in.y); } }