• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 package com.badlogic.gdx.tests;
18 
19 import com.badlogic.gdx.math.Affine2;
20 import com.badlogic.gdx.math.MathUtils;
21 import com.badlogic.gdx.math.Matrix3;
22 import com.badlogic.gdx.math.Vector2;
23 import com.badlogic.gdx.tests.utils.GdxTest;
24 import com.badlogic.gdx.utils.GdxRuntimeException;
25 
26 public class Affine2Test extends GdxTest {
27 
28 	static public final float TOLERANCE = 0.005f;
29 
30 	@Override
create()31 	public void create () {
32 		Vector2 trn = new Vector2(30, 50);
33 		float rot = 35;
34 		float cos = (float)Math.cos(MathUtils.degreesToRadians * rot);
35 		float sin = (float)Math.sin(MathUtils.degreesToRadians * rot);
36 		Vector2 scl = new Vector2(0.42f, 1.19f);
37 		Vector2 shear = new Vector2(0.35f, 0.71f);
38 
39 		Matrix3 mat1 = new Matrix3();
40 		Matrix3 mat2 = new Matrix3();
41 		Affine2 afn1 = new Affine2();
42 		Affine2 afn2 = new Affine2();
43 
44 		// check setter - identity
45 		checkEqual(mat1, new float[] {1, 0, 0, 0, 1, 0, 0, 0, 1});
46 		checkEqual(mat1, mat2.idt());
47 		checkEqual(mat1, afn1);
48 		checkEqual(mat1, afn1.idt());
49 
50 		// check setter - translation
51 		mat1.setToTranslation(trn);
52 		checkEqual(mat1, new float[] {1, 0, 0, 0, 1, 0, trn.x, trn.y, 1});
53 		afn1.setToTranslation(trn);
54 		checkEqual(mat1, afn1);
55 
56 		// check setter - scale
57 		mat1.setToScaling(scl);
58 		checkEqual(mat1, new float[] {scl.x, 0, 0, 0, scl.y, 0, 0, 0, 1});
59 		afn1.setToScaling(scl);
60 		checkEqual(mat1, afn1);
61 
62 		// check setter - rotation
63 		mat1.setToRotation(rot);
64 		checkEqual(mat1, new float[] {cos, sin, 0, -sin, cos, 0, 0, 0, 1});
65 		afn1.setToRotation(rot);
66 		checkEqual(mat1, afn1);
67 		mat1.setToRotationRad(MathUtils.degreesToRadians * rot);
68 		checkEqual(mat1, afn1);
69 		afn1.setToRotationRad(MathUtils.degreesToRadians * rot);
70 		checkEqual(mat1, afn1);
71 
72 		// check setter - shearing
73 		afn1.setToShearing(shear);
74 		checkEqual(mat1.set(afn1), new float[] {1, shear.y, 0, shear.x, 1, 0, 0, 0, 1});
75 
76 		// check setter - translation x rotation x scale
77 		afn1.setToTrnRotScl(trn, rot, scl);
78 		afn2.setToTrnRotRadScl(trn, MathUtils.degreesToRadians * rot, scl);
79 		checkEqual(afn1, afn2);
80 		afn2.setToTranslation(trn).rotate(rot).scale(scl);
81 		checkEqual(afn1, afn2);
82 
83 		// check setter - translation x scale
84 		afn1.setToTrnRotScl(trn, 0, scl);
85 		afn2.setToTrnScl(trn, scl);
86 		checkEqual(afn1, afn2);
87 
88 		// check post-multiplication
89 		mat1.idt().scale(scl).rotate(rot).translate(trn).mul(mat2.set(afn2.setToShearing(shear)));
90 		afn1.idt().scale(scl).rotate(rot).translate(trn).shear(shear);
91 		checkEqual(mat1, afn1);
92 		afn1.idt().mul(afn2.setToScaling(scl)).mul(afn2.setToRotation(rot)).mul(afn2.setToTranslation(trn))
93 			.mul(afn2.setToShearing(shear));
94 		checkEqual(mat1, afn1);
95 
96 		// check pre-multiplication
97 		afn1.idt().preShear(shear).preTranslate(trn).preRotate(rot).preScale(scl);
98 		checkEqual(mat1, afn1);
99 		afn1.idt().preMul(afn2.setToShearing(shear)).preMul(afn2.setToTranslation(trn)).preMul(afn2.setToRotation(rot))
100 			.preMul(afn2.setToScaling(scl));
101 		checkEqual(mat1, afn1);
102 		mat1.set(afn2.setToShearing(shear)).trn(trn).mulLeft(mat2.setToRotation(rot)).mulLeft(mat2.setToScaling(scl));
103 		checkEqual(mat1, afn1);
104 
105 		// check determinant and inverse
106 		checkEqual(mat1.det(), afn1.det());
107 		check(afn1.det() == (afn1.m00 * afn1.m11 - afn1.m01 * afn1.m10));
108 		mat1.inv();
109 		afn2.set(afn1).inv();
110 		checkEqual(mat1, afn2);
111 		checkEqual(afn1.det(), 1 / afn2.det());
112 
113 		// check for exception when trying to invert singular matrices
114 		boolean didThrow = false;
115 		afn1.setToShearing(1, 1);
116 		try {
117 			afn1.inv();
118 		} catch (GdxRuntimeException e) {
119 			didThrow = true;
120 		}
121 		check(didThrow);
122 
123 		System.out.println("All tests passed.");
124 	}
125 
check(boolean condition)126 	private static void check (boolean condition) {
127 		if (!condition) throw new GdxRuntimeException("");
128 	}
129 
check(boolean condition, String msg)130 	private static void check (boolean condition, String msg) {
131 		if (!condition) throw new GdxRuntimeException(msg);
132 	}
133 
checkEqual(Matrix3 matrix, Affine2 affine)134 	private static void checkEqual (Matrix3 matrix, Affine2 affine) {
135 		checkEqual(matrix, new Matrix3().set(affine));
136 	}
137 
checkEqual(Affine2 a, Affine2 b)138 	private static void checkEqual (Affine2 a, Affine2 b) {
139 		checkEqual(new Matrix3().set(a), new Matrix3().set(b));
140 	}
141 
checkEqual(Matrix3 a, Matrix3 b)142 	private static void checkEqual (Matrix3 a, Matrix3 b) {
143 		for (int i = 0; i < 9; i++)
144 			check(MathUtils.isEqual(a.val[i], b.val[i], TOLERANCE), "matrices are not equal");
145 	}
146 
checkEqual(Matrix3 matrix, float[] vals)147 	private static void checkEqual (Matrix3 matrix, float[] vals) {
148 		for (int i = 0; i < 9; i++)
149 			check(MathUtils.isEqual(matrix.val[i], vals[i], TOLERANCE), "matrices are not equal");
150 	}
151 
checkEqual(float a, float b)152 	private static void checkEqual (float a, float b) {
153 		check(MathUtils.isEqual(a, b, TOLERANCE));
154 	}
155 }
156