/*
* Copyright 2013 MovingBlocks
*
* 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 org.terasology.math;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.terasology.math.geom.Vector3f;
import org.terasology.math.geom.Vector3i;
import java.util.HashSet;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
*/
public class Vector3iTest {
private Vector3i v1;
private Vector3i v2;
private Vector3i v3;
public Vector3iTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
v1 = new Vector3i(1, 3, 7);
v2 = new Vector3i(2, 6, 14);
v3 = new Vector3i(3, 9, 21);
}
@After
public void tearDown() {
}
@Test
public void testEmptyConstructor() {
Vector3i v = new Vector3i();
assertEquals(0, v.x);
assertEquals(0, v.y);
assertEquals(0, v.z);
}
@Test
public void testTripleConstructor() {
Vector3i v = new Vector3i(1, 2, 3);
assertEquals(1, v.x);
assertEquals(2, v.y);
assertEquals(3, v.z);
}
@Test
public void testOffsetConstructor() {
Vector3f vOrig = new Vector3f(0.1f, 0.6f, 7.2f);
Vector3i v = new Vector3i(vOrig, 0.5f);
assertEquals(new Vector3i(0, 1, 7), v);
}
@Test
public void testOffsetConstructorWithNegatives() {
Vector3f vOrig = new Vector3f(-0.1f, -0.6f, -1.4f);
Vector3i v = new Vector3i(vOrig, 0.5f);
assertEquals(new Vector3i(0, -1, -1), v);
}
@Test
public void testCopyConstructor() {
Vector3i copy = new Vector3i(v1);
assertEquals(v1.x, copy.x);
assertEquals(v1.y, copy.y);
assertEquals(v1.z, copy.z);
}
@Test
public void testEquals() {
assertFalse(v1.equals(v2));
assertTrue(v1.equals(new Vector3i(v1.x, v1.y, v1.z)));
assertFalse(v1.equals(null));
}
@Test
public void testSetTriple() {
Vector3i v = new Vector3i(v1);
v.set(v2.x, v2.y, v2.z);
assertEquals(v2, v);
}
@Test
public void testSetCopy() {
Vector3i v = new Vector3i();
v.set(v2);
assertEquals(v2, v);
}
@Test
public void testAdd() {
Vector3i v = new Vector3i(v1);
v.add(v2);
assertEquals(v3, v);
}
@Test
public void testAddTriple() {
Vector3i v = new Vector3i(v1);
v.add(v2.x, v2.y, v2.z);
assertEquals(v3, v);
}
@Test
public void testMin() {
Vector3i v = new Vector3i(v1);
v.min(new Vector3i(v1.z, v1.y, v1.x));
assertEquals(Math.min(v1.x, v1.z), v.x);
assertEquals(v1.y, v.y);
assertEquals(Math.min(v1.x, v1.z), v.z);
}
@Test
public void testMax() {
Vector3i v = new Vector3i(v1);
v.max(new Vector3i(v1.z, v1.y, v1.x));
assertEquals(Math.max(v1.x, v1.z), v.x);
assertEquals(v1.y, v.y);
assertEquals(Math.max(v1.x, v1.z), v.z);
}
@Test
public void testManhattanDistance() {
assertEquals(0, Vector3i.zero().gridDistance(Vector3i.zero()));
assertEquals(1, Vector3i.zero().gridDistance(Vector3i.west()));
assertEquals(1, Vector3i.zero().gridDistance(Vector3i.up()));
assertEquals(1, Vector3i.zero().gridDistance(Vector3i.north()));
assertEquals(3, Vector3i.zero().gridDistance(Vector3i.one()));
assertEquals(3, Vector3i.zero().gridDistance(new Vector3i(1, -1, 1)));
}
@Test
public void testHash() {
// k = 59
// j = k+1 = 60
// i = (k+k^2)(1+k)^2 = not important for collision
// hash = (k+k^2)(1+k)^2 + x(1+k)^2 + (1+k)y + z
// hash = i + xj^2 + jy + z
// with x := 0
// hash = i + jy + z
// set i + jy + z = i + jy' + z'
// jy + z = jy' + z'
// set z' := z + j -> z'-z = j
// jy = jy' + j -> y' = y - 1
Vector3i a = new Vector3i(0, 10, 10);
Vector3i b = new Vector3i(0, 9, 70);
assertFalse(a.hashCode() == b.hashCode());
assertTrue(new Vector3i(0, 10, 10).hashCode() == new Vector3i(0, 10, 10).hashCode());
assertTrue(new Vector3i(-100, 10, 10).hashCode() == new Vector3i(-100, 10, 10).hashCode());
assertTrue(new Vector3i(0, -5, -5).hashCode() == new Vector3i(0, -5, -5).hashCode());
assertFalse(new Vector3i(1, 10, 10).hashCode() == new Vector3i(0, 10, 10).hashCode());
assertFalse(new Vector3i(-101, 10, 10).hashCode() == new Vector3i(-100, 10, 10).hashCode());
assertFalse(new Vector3i(0, -1, -5).hashCode() == new Vector3i(0, -5, -5).hashCode());
}
@Test
public void testHashCollisions() {
int range = 50;
Set<Integer> alreadyUsedHashes = new HashSet<>();
for (int x = -range; x < range; ++x) {
for (int y = -range; y < range; ++y) {
for (int z = -range; z < range; ++z) {
int hash = new Vector3i(x, y, z).hashCode();
if (alreadyUsedHashes.contains(hash)) {
fail(String.format("duplicate hash %d at: %d,%d,%d", hash, x, y, z));
} else {
alreadyUsedHashes.add(hash);
}
}
}
}
}
}