Package org.terasology.math

Source Code of org.terasology.math.TeraMathTest

/*
* 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.Test;
import org.terasology.config.Config;
import org.terasology.registry.CoreRegistry;

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 TeraMathTest {

    private static final double MAX_DOUBLE_ERROR = 0.00001;


    @Test
    public void getEdgeRegion() {
        Region3i region = Region3i.createFromMinAndSize(new Vector3i(16, 0, 16), new Vector3i(16, 128, 16));
        assertEquals(Region3i.createFromMinMax(new Vector3i(16, 0, 16), new Vector3i(16, 127, 31)), TeraMath.getEdgeRegion(region, Side.LEFT));
    }

    // This function mimicks a power function using ints only
    private long longPow(int base, int exp) {
        // MAX_DOUBLE_ERROR fixes small rounding errors
        double result = Math.pow(base, exp);
        if (!TeraMath.isFinite(result)) {
            throw new ArithmeticException(Double.toString(result));
        }
        if (result < 0) {
            return (long) (result - MAX_DOUBLE_ERROR);
        }
        return (long) (result + MAX_DOUBLE_ERROR);
    }

    @Test
    public void powDouble() {
        for (int exp = -5; exp <= 5; exp++) {
            for (double base = -10.0; base <= 10.0; base += 0.2f) {
                assertEqualsRatio(base + "^" + exp, Math.pow(base, exp), TeraMath.pow(base, exp), MAX_DOUBLE_ERROR);
            }
        }
    }

    @Test
    public void powInt() {
        // Only from -2 because most negative exponents return a 0
        for (int exp = -2; exp <= 8; exp++) {
            for (int base = -8; base <= 8; base++) {
                long javaMathResult = 9001;
                boolean exception = false;
                try {
                    javaMathResult = longPow(base, exp);
                } catch (ArithmeticException e) {
                    exception = true;
                }

                try {
                    int result = TeraMath.pow(base, exp);
                    assertFalse("(int)" + base + "^" + exp + " did not throw an exception as expected", exception);
                    assertEquals(base + "^" + exp, javaMathResult, (long) result);
                } catch (ArithmeticException e) {
                    assertTrue("(int)" + base + "^" + exp + " threw an unexpected exception", exception);
                }

                try {
                    long result = TeraMath.pow((long) base, exp);
                    assertFalse("(long)" + base + "^" + exp + " did not throw an exception as expected", exception);
                    assertEquals(base + "^" + exp, javaMathResult, result);
                } catch (ArithmeticException e) {
                    assertTrue("(long)" + base + "^" + exp + " threw an unexpected exception", exception);
                }
            }
        }
    }


    // JUnit's assertEquals(expected, value, delta) uses delta as the maximum difference from expected and value
    // This approach is not acceptable for large doubles whose precision decreases as numbers grows
    // Therefore this function uses delta as the maximum deviation of the actual from the expected value
    private void assertEqualsRatio(String msg, double expected, double actual, double error) {
        // If not finite, ignore error. Its value must be exact
        if (!TeraMath.isFinite(expected) && expected != actual) {
            fail(msg);
            return;
        }

        double ratio = expected / actual;
        if (ratio < 0.0) {
            ratio = 1.0 / ratio;
        }
        ratio = TeraMath.fastAbs(ratio - 1.0);
        if (ratio >= error) {
            fail(msg);
        }
    }

    @Test
    public void regionPositions() {
        CoreRegistry.put(Config.class, new Config());

        assertEquals(1, TeraMath.calcChunkPos(Region3i.createFromMinMax(new Vector3i(0, 0, 0), new Vector3i(0, 0, 0))).length);
        assertEquals(1, TeraMath.calcChunkPos(Region3i.createFromMinMax(new Vector3i(0, 0, 0), new Vector3i(31, 63, 31))).length);
        assertEquals(2, TeraMath.calcChunkPos(Region3i.createFromMinMax(new Vector3i(0, 0, 0), new Vector3i(32, 63, 31))).length);
        assertEquals(4, TeraMath.calcChunkPos(Region3i.createFromMinMax(new Vector3i(0, 0, 0), new Vector3i(32, 63, 32))).length);
        assertEquals(8, TeraMath.calcChunkPos(Region3i.createFromMinMax(new Vector3i(0, 0, 0), new Vector3i(32, 64, 32))).length);
        assertEquals(12, TeraMath.calcChunkPos(Region3i.createFromMinMax(new Vector3i(-1, 0, 0), new Vector3i(32, 64, 32))).length);

        Vector3i[] chunks = TeraMath.calcChunkPos(Region3i.createFromMinMax(new Vector3i(0, 0, 0), new Vector3i(32, 63, 31)));
        assertEquals(new Vector3i(0, 0, 0), chunks[0]);
        assertEquals(new Vector3i(1, 0, 0), chunks[1]);
    }
}
TOP

Related Classes of org.terasology.math.TeraMathTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.