mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-16 04:33:56 -07:00
This commit adds an additional method to Location to set the direction of facing. Included are a set of unit tests that ensure the consistency of getDirection and setDirection using a set of cardinal directions and arbituary data points. Javadocs were also added to pitch and yaw methods that explain the unit and points of origin. By: Wesley Wolfe <weswolf@aol.com>
197 lines
5.7 KiB
Java
197 lines
5.7 KiB
Java
package org.bukkit;
|
|
|
|
import static org.hamcrest.Matchers.*;
|
|
import static org.junit.Assert.*;
|
|
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
|
|
import org.bukkit.util.Vector;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.junit.runners.Parameterized;
|
|
import org.junit.runners.Parameterized.Parameter;
|
|
import org.junit.runners.Parameterized.Parameters;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
|
|
@RunWith(Parameterized.class)
|
|
public class LocationTest {
|
|
private static final double δ = 1.0 / 1000000;
|
|
/**
|
|
* <pre>
|
|
* a² + b² = c², a = b
|
|
* => 2∙(a²) = 2∙(b²) = c², c = 1
|
|
* => 2∙(a²) = 1
|
|
* => a² = 1/2
|
|
* => a = √(1/2) ∎
|
|
* </pre>
|
|
*/
|
|
private static final double HALF_UNIT = Math.sqrt(1 / 2f);
|
|
/**
|
|
* <pre>
|
|
* a² + b² = c², c = √(1/2)
|
|
* => a² + b² = √(1/2)², a = b
|
|
* => 2∙(a²) = 2∙(b²) = 1/2
|
|
* => a² = 1/4
|
|
* => a = √(1/4) ∎
|
|
* </pre>
|
|
*/
|
|
private static final double HALF_HALF_UNIT = Math.sqrt(1 / 4f);
|
|
|
|
@Parameters(name= "{index}: {0}")
|
|
public static List<Object[]> data() {
|
|
Random RANDOM = new Random(1l); // Test is deterministic
|
|
int r = 0;
|
|
return ImmutableList.<Object[]>of(
|
|
new Object[] { "X",
|
|
1, 0, 0,
|
|
270, 0
|
|
},
|
|
new Object[] { "-X",
|
|
-1, 0, 0,
|
|
90, 0
|
|
},
|
|
new Object[] { "Z",
|
|
0, 0, 1,
|
|
0, 0
|
|
},
|
|
new Object[] { "-Z",
|
|
0, 0, -1,
|
|
180, 0
|
|
},
|
|
new Object[] { "Y",
|
|
0, 1, 0,
|
|
0, -90 // Zero is here as a "default" value
|
|
},
|
|
new Object[] { "-Y",
|
|
0, -1, 0,
|
|
0, 90 // Zero is here as a "default" value
|
|
},
|
|
new Object[] { "X Z",
|
|
HALF_UNIT, 0, HALF_UNIT,
|
|
(270 + 360) / 2, 0
|
|
},
|
|
new Object[] { "X -Z",
|
|
HALF_UNIT, 0, -HALF_UNIT,
|
|
(270 + 180) / 2, 0
|
|
},
|
|
new Object[] { "-X -Z",
|
|
-HALF_UNIT, 0, -HALF_UNIT,
|
|
(90 + 180) / 2, 0
|
|
},
|
|
new Object[] { "-X Z",
|
|
-HALF_UNIT, 0, HALF_UNIT,
|
|
(90 + 0) / 2, 0
|
|
},
|
|
new Object[] { "X Y Z",
|
|
HALF_HALF_UNIT, HALF_UNIT, HALF_HALF_UNIT,
|
|
(270 + 360) / 2, -45
|
|
},
|
|
new Object[] { "-X -Y -Z",
|
|
-HALF_HALF_UNIT, -HALF_UNIT, -HALF_HALF_UNIT,
|
|
(90 + 180) / 2, 45
|
|
},
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++),
|
|
getRandom(RANDOM, r++)
|
|
);
|
|
}
|
|
|
|
private static Object[] getRandom(Random random, int index) {
|
|
final double YAW_FACTOR = 360;
|
|
final double YAW_OFFSET = 0;
|
|
final double PITCH_FACTOR = 180;
|
|
final double PITCH_OFFSET = -90;
|
|
final double CARTESIAN_FACTOR = 256;
|
|
final double CARTESIAN_OFFSET = -128;
|
|
|
|
Vector vector;
|
|
Location location;
|
|
if (random.nextBoolean()) {
|
|
float pitch = (float) (random.nextDouble() * PITCH_FACTOR + PITCH_OFFSET);
|
|
float yaw = (float) (random.nextDouble() * YAW_FACTOR + YAW_OFFSET);
|
|
|
|
location = getEmptyLocation();
|
|
location.setPitch(pitch);
|
|
location.setYaw(yaw);
|
|
|
|
vector = location.getDirection();
|
|
} else {
|
|
double x = random.nextDouble() * CARTESIAN_FACTOR + CARTESIAN_OFFSET;
|
|
double y = random.nextDouble() * CARTESIAN_FACTOR + CARTESIAN_OFFSET;
|
|
double z = random.nextDouble() * CARTESIAN_FACTOR + CARTESIAN_OFFSET;
|
|
|
|
location = getEmptyLocation();
|
|
vector = new Vector(x, y, z).normalize();
|
|
|
|
location.setDirection(vector);
|
|
}
|
|
|
|
return new Object[] { "R" + index,
|
|
vector.getX(), vector.getY(), vector.getZ(),
|
|
location.getYaw(), location.getPitch()
|
|
};
|
|
}
|
|
|
|
@Parameter(0)
|
|
public String nane;
|
|
@Parameter(1)
|
|
public double x;
|
|
@Parameter(2)
|
|
public double y;
|
|
@Parameter(3)
|
|
public double z;
|
|
@Parameter(4)
|
|
public float yaw;
|
|
@Parameter(5)
|
|
public float pitch;
|
|
|
|
@Test
|
|
public void testExpectedPitchYaw() {
|
|
Location location = getEmptyLocation().setDirection(getVector());
|
|
|
|
assertThat((double) location.getYaw(), is(closeTo(yaw, δ)));
|
|
assertThat((double) location.getPitch(), is(closeTo(pitch, δ)));
|
|
}
|
|
|
|
@Test
|
|
public void testExpectedXYZ() {
|
|
Vector vector = getLocation().getDirection();
|
|
|
|
assertThat(vector.getX(), is(closeTo(x, δ)));
|
|
assertThat(vector.getY(), is(closeTo(y, δ)));
|
|
assertThat(vector.getZ(), is(closeTo(z, δ)));
|
|
}
|
|
|
|
private Vector getVector() {
|
|
return new Vector(x, y, z);
|
|
}
|
|
|
|
private static Location getEmptyLocation() {
|
|
return new Location(null, 0, 0, 0);
|
|
}
|
|
|
|
private Location getLocation() {
|
|
Location location = getEmptyLocation();
|
|
location.setYaw(yaw);
|
|
location.setPitch(pitch);
|
|
return location;
|
|
}
|
|
}
|