/**
* Copyright 2011 The ForPlay Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package forplay.core;
/**
* TODO
*/
public class Transform {
/**
* TODO
*/
public static final Transform IDENTITY = new Transform(1, 0, 0, 1, 0, 0);
private float m00, m01, m10, m11;
private float tx, ty;
/**
* TODO
*/
public Transform() {
setIdentity();
}
/**
* TODO
*/
public Transform(float m00, float m01, float m10, float m11, float tx, float ty) {
set(m00, m01, m10, m11, tx, ty);
}
/**
* TODO
*/
public Transform(Transform toCopy) {
copy(toCopy);
}
/**
* TODO
*/
public void copy(Transform toCopy) {
m00 = toCopy.m00; m01 = toCopy.m01;
m10 = toCopy.m10; m11 = toCopy.m11;
tx = toCopy.tx; ty = toCopy.ty;
}
/**
* TODO
*/
public float m00() {
return m00;
}
/**
* TODO
*/
public float m01() {
return m01;
}
/**
* TODO
*/
public float m10() {
return m10;
}
/**
* TODO
*/
public float m11() {
return m11;
}
/**
* TODO
*/
public void rotate(float angle) {
float sr = (float) Math.sin(angle);
float cr = (float) Math.cos(angle);
transform(cr, sr, -sr, cr, 0, 0);
}
/**
* TODO
*/
public void scale(float sx, float sy) {
m00 *= sx; m10 *= sy;
m01 *= sx; m11 *= sy;
tx *= sx; ty *= sy;
}
/**
* TODO
*/
public void set(float m00, float m01, float m10, float m11, float tx, float ty) {
this.m00 = m00; this.m01 = m01;
this.m10 = m10; this.m11 = m11;
this.tx = tx; this.ty = ty;
}
/**
* TODO
*/
public void setIdentity() {
m00 = 1; m10 = 0;
m01 = 0; m11 = 1;
tx = 0; ty = 0;
}
/**
* TODO
*/
public void setM00(float m00) {
this.m00 = m00;
}
/**
* TODO
*/
public void setM01(float m01) {
this.m01 = m01;
}
/**
* TODO
*/
public void setM10(float m10) {
this.m10 = m10;
}
/**
* TODO
*/
public void setM11(float m11) {
this.m11 = m11;
}
/**
* TODO
*/
public void setTx(float tx) {
this.tx = tx;
}
/**
* TODO
*/
public void setTy(float ty) {
this.ty = ty;
}
/**
* TODO
*/
public void setTranslation(float tx, float ty) {
setTx(tx);
setTy(ty);
}
/**
* TODO
*
* TODO: This method does not preserve shear. Is that worth the trouble?
*/
public void setRotation(float angle) {
// Decompose scale.
float sx = len(m00, m01);
float sy = len(m10, m11);
// Apply rotation and scale together.
float sr = (float) Math.sin(angle);
float cr = (float) Math.cos(angle);
m00 = cr * sx; m01 = sr * sx;
m10 = -sr * sy; m11 = cr * sy;
}
/**
* TODO
*/
public void setScale(float s) {
setScale(s, s);
}
/**
* TODO
*/
public void setScale(float sx, float sy) {
// Normalize to scale = 1.
float osx = len(m00, m01);
float osy = len(m10, m11);
m00 /= osx; m01 /= osx;
m10 /= osy; m11 /= osy;
// Then re-apply.
m00 *= sx; m01 *= sx;
m10 *= sy; m11 *= sy;
}
/**
* TODO
*/
public void setScaleX(float sx) {
// Normalize to scale = 1.
float osx = len(m00, m01);
m00 /= osx; m01 /= osx;
// Then re-apply.
m00 *= sx; m01 *= sx;
}
/**
* TODO
*/
public void setScaleY(float sy) {
// Normalize to scale = 1.
float osy = len(m10, m11);
m10 /= osy; m11 /= osy;
// Then re-apply.
m10 *= sy; m11 *= sy;
}
@Override
public String toString() {
return "[" +
m00() + " " + m01() + "\n " +
m10() + " " + m11() + "\n " +
tx() + " " + ty() +
"]";
}
/**
* TODO
*/
public void transform(float m00, float m01, float m10, float m11, float tx, float ty) {
transform(m00, m01, m10, m11, tx, ty, this);
}
/**
* TODO
*/
public void transform(float m00, float m01, float m10, float m11, float tx, float ty,
Transform out) {
float out00 = this.m00 * m00 + this.m10 * m01, out10 = this.m00 * m10 + this.m10 * m11;
float out01 = this.m01 * m00 + this.m11 * m01, out11 = this.m01 * m10 + this.m11 * m11;
float outx = this.m00 * tx + this.m10 * ty + this.tx;
float outy = this.m01 * tx + this.m11 * ty + this.ty;
out.m00 = out00; out.m01 = out01;
out.m10 = out10; out.m11 = out11;
out.tx = outx; out.ty = outy;
}
/**
* TODO
*/
public void transform(Transform t) {
transform(t.m00, t.m01, t.m10, t.m11, t.tx, t.ty);
}
/**
* TODO
*/
public void transform(Transform t, Transform out) {
transform(t.m00, t.m01, t.m10, t.m11, t.tx, t.ty, out);
}
/**
* TODO
*/
public void translate(float x, float y) {
transform(1, 0, 0, 1, x, y);
}
/**
* TODO
*/
public float tx() {
return tx;
}
/**
* TODO
*/
public float ty() {
return ty;
}
/**
* TODO
*/
public float scaleX() {
return len(m00, m01);
}
/**
* TODO
*/
public float scaleY() {
return len(m10, m11);
}
private float len(float x, float y) {
return (float) Math.sqrt(x * x + y * y);
}
}