/**
* Copyright (c) 2009-2011, chunquedong(YangJiandong)
*
* This file is part of ChunMap project
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
*
* History:
* 2010-05-05 Jed Young Creation
*/
package chunmap.model.crs.transf;
import chunmap.model.coord.Coordinate2D;
import chunmap.model.coord.CPoint;
import chunmap.model.coord.Transform;
import chunmap.util.math.Matrix;
import chunmap.util.math.Matrix.MatrixException;
/**
* 仿射变换
*
* @author chunquedong
*
*/
public class AffineTransform implements Transform {
private Matrix m;
private AffineTransform reverseTransform;
public AffineTransform(Matrix m) {
this.m = m;
}
public AffineTransform() {
m = new Matrix(3, 3);
}
public double get(int r, int c) {
return m.get(r, c);
}
public void set(int r, int c, double value) {
m.set(r, c, value);
}
public Matrix getMatrix() {
return m;
}
public void setMatrix(Matrix m) {
this.m = m;
}
@Override
public CPoint convert(CPoint p) {
Matrix sour = new Matrix(1, 3);
sour.set(0, 0, p.getX());
sour.set(0, 1, p.getY());
sour.set(0, 2, 1);
Matrix result = sour.matrixMulti(m);
double x = result.get(0, 0);
double y = result.get(0, 1);
return new Coordinate2D(x, y);
}
/**
* 逆变换
*
* @return
*/
public AffineTransform getReverseTransform() {
if (reverseTransform == null) {
try {
reverseTransform = new AffineTransform(getMatrix().matrixInv());
} catch (MatrixException e) {
reverseTransform = new AffineTransform(getMatrix());
e.printStackTrace();
}
}
return reverseTransform;
}
/**
* 叠加变换
*
* @param other
* @return
*/
public AffineTransform accumulate(AffineTransform other) {
Matrix newMatrix = this.getMatrix().matrixMulti(other.getMatrix());
AffineTransform trans = new AffineTransform();
trans.setMatrix(newMatrix);
return trans;
}
public java.awt.geom.AffineTransform toAwtAffineTransform() {
Matrix nm = m.matrixTrans();
return new java.awt.geom.AffineTransform(nm.get(0, 0), nm.get(1, 0), nm
.get(0, 1), nm.get(1, 1), nm.get(0, 2), nm.get(1, 2));
}
// ------------------------------------------------------------预定义变换模板
/**
* 平移变换
*
* @param tx
* @param ty
* @return
*/
public static AffineTransform pan(double tx, double ty) {
AffineTransform at = new AffineTransform();
at.set(0, 0, 1);
at.set(1, 1, 1);
at.set(2, 2, 1);
at.set(2, 0, tx);
at.set(2, 1, ty);
return at;
}
/**
* 缩放变换
*
* @param sx
* @param sy
* @return
*/
public static AffineTransform scale(double x0, double y0, double sx,
double sy) {
AffineTransform at = new AffineTransform();
at.set(0, 0, sx);
at.set(1, 1, sy);
at.set(2, 2, 1);
at.set(2, 0, (1 - sx) * x0);
at.set(2, 1, (1 - sy) * y0);
return at;
}
/**
* 对称变换
*
* @param a
* @param b
* @param d
* @param e
* @return
*/
public static AffineTransform symmetry(double a, double b, double d,
double e) {
AffineTransform at = new AffineTransform();
at.set(0, 0, a);
at.set(1, 1, e);
at.set(2, 2, 1);
at.set(0, 1, d);
at.set(1, 0, b);
return at;
}
/**
* 旋转变换
*
* @param thta
* @return
*/
public static AffineTransform rotate(double x, double y, double thta) {
AffineTransform at = new AffineTransform();
at.set(0, 0, Math.cos(thta));
at.set(1, 1, Math.cos(thta));
at.set(2, 2, 1);
at.set(0, 1, Math.sin(thta));
at.set(1, 0, -Math.sin(thta));
at.set(2, 0, (1 - Math.cos(thta)) * x + (y * Math.sin(thta)));
at.set(2, 1, (1 + Math.cos(thta)) * y - (x * Math.sin(thta)));
return at;
}
/**
* 错切变换
*
* @param b
* @param d
* @return
*/
public static AffineTransform shear(double b, double d) {
AffineTransform at = new AffineTransform();
at.set(0, 0, 1);
at.set(1, 1, 1);
at.set(2, 2, 1);
at.set(0, 1, d);
at.set(1, 0, b);
return at;
}
public static AffineTransform unit() {
AffineTransform at = new AffineTransform(Matrix.unitMatrix(3));
return at;
}
}