Files
gzz-mirror/Modules/awtool/AwtMetrics.zob
2026-09-14 20:19:29 -04:00

327 lines
10 KiB
Plaintext

/*
AwtMetrics.java
*
* Copyright (c) 2000, Ted Nelson and Tuomas Lukka
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software 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 README
* file for more details.
*
*/
/*
* Written by Kimmo Wideroos
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.awt.*;
/** Abstract class for different metrics (in order to get different
* focus+context effects)
*/
public abstract class AwtMetrics extends ZObCellRepr implements ZOb {
public static boolean dbg = true;
static void p(String s) { if(dbg) System.out.println(s); }
static void pa(String s) { System.out.println(s); }
STRUCTPARAMS {
int[] RealView
= { 400, 400 };
int[] VirtualView
= { 400, 400 };
double[] Origo
= { 0.0, 0.0 };
int[] FocusOrigo
= { 200, 200 };
boolean GridOn
= true;
}
static ZZCell FocusedCell = null;
double FocusCoefficient = focusCoefficientMinimum();
abstract double focusCoefficientMinimum();
abstract double focusCoefficientMaximum();
public double[] RealViewd() {
return new double[] { (double)RealView[0], (double)RealView[1] };
}
public double[] RealViewHalfd() {
return new double[] { (double)RealView[0]*0.5, (double)RealView[1]*0.5 };
}
public void setRealView(int x, int y, boolean adjustFocus) {
if(adjustFocus) {
double[] rvd = RealViewd();
double newfox = ((double)(x*FocusOrigo[0]))/rvd[0];
double newfoy = ((double)(y*FocusOrigo[1]))/rvd[1];
setFocusOrigo((int)newfox, (int)newfoy);
}
RealView[0] = x; RealView[1] = y;
}
public void setRealView(Dimension d, boolean adjustFocus) {
setRealView(d.width, d.height, adjustFocus);
}
public double[] VirtualViewd() {
return new double[] { (double)VirtualView[0], (double)VirtualView[1] };
}
public double[] VirtualViewHalfd() {
return new double[] { (double)VirtualView[0]*0.5, (double)VirtualView[1]*0.5 };
}
public void setVirtualView(int x, int y) {
VirtualView[0] = x; VirtualView[1] = y;
}
public void setOrigo(double ox, double oy) {
Origo[0] = ox;
Origo[1] = oy;
}
public void moveOrigo(double dox, double doy) {
Origo[0] += dox;
Origo[1] += doy;
}
public double[] FocusOrigod() {
return new double[] { (double)FocusOrigo[0], (double)FocusOrigo[1] };
}
public void setFocusOrigo(int fox, int foy) {
setFocusOrigo(fox, foy, null);
}
public void setFocusOrigo(int fox, int foy, ZZCell focusCell) {
FocusOrigo[0] = fox;
FocusOrigo[1] = foy;
if(focusCell != null && focusCell == FocusedCell) {
FocusCoefficient += 1.0;
if(FocusCoefficient > focusCoefficientMaximum())
FocusCoefficient = focusCoefficientMaximum();
} else {
FocusCoefficient = focusCoefficientMinimum();
FocusedCell = focusCell;
}
}
public void init(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy) {
setCell(start);
setRealView(rv.width, rv.height, false);
setVirtualView(vv.width, vv.height);
setOrigo(ox, oy);
setFocusOrigo(rv.width>>1, rv.height>>1);
}
public AwtMetrics() { }
public AwtMetrics(ZZCell start, Dimension rv, Dimension vv,
double ox, double oy)
{
init(start, rv, vv, ox, oy);
}
private Point mapToUnfocusedRealView(double x, double y) {
int rx, ry;
double[] vvhd = VirtualViewHalfd(), rvhd = RealViewHalfd();
rx = (int)(( (x-Origo[0]) * vvhd[0]) + rvhd[0]);
ry = (int)(( (y-Origo[1]) * vvhd[1]) + rvhd[1]);
return new Point(rx, ry);
}
/** mapping from 'virtualview' (=modelview, coordinates
* -1.0<x,y<1.0) to 'realview' (coordinates in this.RealView).
* can be used for example in order to gain an illusion of focus+context
* by demagnifying areas near focus. ceturns 'realview' coordinates.
* @param x x-coordinate ranging from -infinity ... infinity
* @param y y-coordinate
*/
public Point mapToRealView(double x, double y) {
Point ufr; // unfocused realview point
ufr = mapToUnfocusedRealView(x, y);
return focusRealView(ufr.x, ufr.y);
}
/** reverse mapping, see 'mapToRealView' */
public double[] mapToVirtualView(int rx, int ry) {
double x, y;
double[] vvhd = VirtualViewHalfd(), rvhd = RealViewHalfd();
Point iCoord = inverseTransform(rx, ry);
x = (((double)iCoord.x - rvhd[0]) / vvhd[0]) + Origo[0];
y = (((double)iCoord.y - rvhd[1]) / vvhd[1]) + Origo[1];
return new double[] { x, y };
}
public Point mapToRealView(double[] coord) {
return mapToRealView(coord[0], coord[1]);
}
public Point focusRealView(int x, int y) {
double xFocus, yFocus, dx, dy;
double[] d;
double[] vvhd = VirtualViewHalfd();
xFocus = (double)(x - FocusOrigo[0]);
yFocus = (double)(y - FocusOrigo[1]);
d = transformAtFocusNbhood(xFocus/vvhd[0], yFocus/vvhd[1]);
return new Point(FocusOrigo[0]+(int)(vvhd[0]*d[0]), FocusOrigo[1]+(int)(vvhd[1]*d[1]));
}
public Point inverseTransform(int x, int y) {
double xFocus, yFocus, dx, dy;
double[] d;
double[] vvhd = VirtualViewHalfd();
xFocus = (double)(x - FocusOrigo[0]);
yFocus = (double)(y - FocusOrigo[1]);
d = inverseTransformAtFocusNbhood(xFocus/vvhd[0], yFocus/vvhd[1]);
return new Point(FocusOrigo[0]+(int)(vvhd[0]*d[0]), FocusOrigo[1]+(int)(vvhd[1]*d[1]));
}
public double[] getVirtualDimension(int x, int y, Dimension dim) {
double s = getInverseScalingValue(x, y);
double[] vvhd = VirtualViewHalfd();
return new double[] {s*(double)dim.width/vvhd[0], s*(double)dim.height/vvhd[1]};
}
public Dimension getRealDimension(double x, double y, double[] dim) {
double s = getScalingValue(x, y);
double[] vvhd = VirtualViewHalfd();
return new Dimension((int)(s*(double)dim[0]*vvhd[0]), (int)(s*(double)dim[1]*vvhd[1]));
}
abstract public double[] transformAtFocusNbhood(double x, double y,
double focusCoeff);
abstract public double[] inverseTransformAtFocusNbhood(double x, double
y, double focusCoeff);
abstract public double transformScalingValue(double s);
public double[] transformAtFocusNbhood(double x, double y) {
return transformAtFocusNbhood(x, y, FocusCoefficient);
}
public double[] inverseTransformAtFocusNbhood(double x, double y) {
return inverseTransformAtFocusNbhood(x, y, FocusCoefficient);
}
public double getScalingValue(double x, double y) {
double d1x, d1y, d2x, d2y, s;
Point ufr, invf; // unfocused realview point, inverse focus point
Point rPoint = mapToRealView(x, y);
d1x = (double)(rPoint.x-FocusOrigo[0]);
d1y = (double)(rPoint.y-FocusOrigo[1]);
ufr = mapToUnfocusedRealView(x, y);
invf = inverseTransform(FocusOrigo[0], FocusOrigo[1]);
d2x = (double)(ufr.x-invf.x);
d2y = (double)(ufr.y-invf.y);
s = Math.sqrt((d1x*d1x + d1y*d1y)/(d2x*d2x + d2y*d2y));
return transformScalingValue(s);
}
public double getInverseScalingValue(int rx, int ry) {
double d1x, d1y, d2x, d2y, s;
Point ufr, invf; // unfocused realview point, inverse focus point
d1x = rx-FocusOrigo[0];
d1y = ry-FocusOrigo[1];
ufr = inverseTransform(rx, ry);
invf = inverseTransform(FocusOrigo[0], FocusOrigo[1]);
d2x = (double)(ufr.x-invf.x);
d2y = (double)(ufr.y-invf.y);
s = Math.sqrt((d2x*d2x + d2y*d2y)/(d1x*d1x + d1y*d1y));
return transformScalingValue(s);
}
public boolean RealViewEquals(Dimension view) {
if(view.width==RealView[0] && view.height==RealView[1])
return true;
return false;
}
/** Write the parameters of this ZOb back in the cellstructure.
* Returns a string describing the errors encountered, or null if
* everything went fine..
* @param c starting cell
* @param clone whether or not to make the new ZOb centralcell a clone
* of the former centralcell (if cells equal, the whole
* issue is trivial).
*/
String cellRepr(ZZCell start, boolean clone) {
ZZCell c2, c = start.getOrNewCell("d.1");
start.setText(getZObName());
c.setText(getZObClassName());
c = c2 = c.getOrNewCell("d.1");
c.setText("RealView");
c = c.getOrNewCell("d.1");
c.setText(""+RealView[0]);
c = c.getOrNewCell("d.1");
c.setText(""+RealView[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("VirtualView");
c = c.getOrNewCell("d.1");
c.setText(""+VirtualView[0]);
c = c.getOrNewCell("d.1");
c.setText(""+VirtualView[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("Origo");
c = c.getOrNewCell("d.1");
c.setText(""+Origo[0]);
c = c.getOrNewCell("d.1");
c.setText(""+Origo[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("FocusOrigo");
c = c.getOrNewCell("d.1");
c.setText(""+FocusOrigo[0]);
c = c.getOrNewCell("d.1");
c.setText(""+FocusOrigo[1]);
c = c2 = c2.getOrNewCell("d.2");
c.setText("GridOn");
c = c.getOrNewCell("d.1");
c.setText(""+GridOn);
return "";
}
}