160 lines
5.7 KiB
C#
160 lines
5.7 KiB
C#
using Microsoft.Xna.Framework;
|
|
using System;
|
|
using Xunit;
|
|
|
|
namespace SemiColinGames.Tests {
|
|
public class GeometryTests {
|
|
|
|
private void AssertVectorsEqual(Vector2 v1, Vector2 v2) {
|
|
Assert.Equal(v1.X, v2.X, 5);
|
|
Assert.Equal(v1.Y, v2.Y, 5);
|
|
}
|
|
|
|
[Fact]
|
|
public void TestVector2Rotate() {
|
|
Vector2 v = new Vector2(10, 0);
|
|
AssertVectorsEqual(new Vector2(10, 0), v.Rotate(FMath.DegToRad(0)));
|
|
AssertVectorsEqual(new Vector2(0, 10), v.Rotate(FMath.DegToRad(90)));
|
|
AssertVectorsEqual(new Vector2(-10, 0), v.Rotate(FMath.DegToRad(180)));
|
|
AssertVectorsEqual(new Vector2(0, -10), v.Rotate(FMath.DegToRad(270)));
|
|
AssertVectorsEqual(new Vector2(10, 0), v.Rotate(FMath.DegToRad(360)));
|
|
AssertVectorsEqual(new Vector2(0, 10), v.Rotate(FMath.DegToRad(450)));
|
|
|
|
AssertVectorsEqual(new Vector2(0, -10), v.Rotate(FMath.DegToRad(-90)));
|
|
AssertVectorsEqual(new Vector2(-10, 0), v.Rotate(FMath.DegToRad(-180)));
|
|
AssertVectorsEqual(new Vector2(0, 10), v.Rotate(FMath.DegToRad(-270)));
|
|
AssertVectorsEqual(new Vector2(10, 0), v.Rotate(FMath.DegToRad(-360)));
|
|
AssertVectorsEqual(new Vector2(0, -10), v.Rotate(FMath.DegToRad(-450)));
|
|
|
|
AssertVectorsEqual(new Vector2(7.0710678f, 7.0710678f), v.Rotate(FMath.DegToRad(45)));
|
|
AssertVectorsEqual(new Vector2(8.6602540f, 5f), v.Rotate(FMath.DegToRad(30)));
|
|
AssertVectorsEqual(new Vector2(5f, 8.6602540f), v.Rotate(FMath.DegToRad(60)));
|
|
AssertVectorsEqual(new Vector2(-5f, 8.6602540f), v.Rotate(FMath.DegToRad(120)));
|
|
AssertVectorsEqual(new Vector2(-8.6602540f, 5f), v.Rotate(FMath.DegToRad(150)));
|
|
|
|
AssertVectorsEqual(new Vector2(7.0710678f, -7.0710678f), v.Rotate(FMath.DegToRad(-45)));
|
|
AssertVectorsEqual(new Vector2(8.6602540f, -5f), v.Rotate(FMath.DegToRad(-30)));
|
|
AssertVectorsEqual(new Vector2(5f, -8.6602540f), v.Rotate(FMath.DegToRad(-60)));
|
|
AssertVectorsEqual(new Vector2(-5f, -8.6602540f), v.Rotate(FMath.DegToRad(-120)));
|
|
AssertVectorsEqual(new Vector2(-8.6602540f, -5f), v.Rotate(FMath.DegToRad(-150)));
|
|
}
|
|
|
|
[Fact]
|
|
public void TestIntersectSegmentNotColliding() {
|
|
AABB box = new AABB(new Vector2(0, 0), new Vector2(8, 8));
|
|
Assert.Null(box.IntersectSegment(new Vector2(-16, -16), new Vector2(32, 0)));
|
|
}
|
|
|
|
[Fact]
|
|
public void TestIntersectSegmentHit() {
|
|
AABB box = new AABB(new Vector2(0, 0), new Vector2(8, 8));
|
|
var point = new Vector2(-16, 4);
|
|
var delta = new Vector2(32, 0);
|
|
Hit? maybeHit = box.IntersectSegment(point, delta);
|
|
|
|
Assert.NotNull(maybeHit);
|
|
Hit hit = (Hit) maybeHit;
|
|
|
|
Assert.Equal(box, hit.Collider);
|
|
Assert.Equal(0.25, hit.Time);
|
|
|
|
Assert.Equal(point.X + delta.X * hit.Time, hit.Position.X);
|
|
Assert.Equal(point.Y + delta.Y * hit.Time, hit.Position.Y);
|
|
|
|
Assert.Equal((1.0f - hit.Time) * -delta.X, hit.Delta.X);
|
|
Assert.Equal((1.0f - hit.Time) * -delta.Y, hit.Delta.Y);
|
|
|
|
Assert.Equal(-1, hit.Normal.X);
|
|
Assert.Equal(0, hit.Normal.Y);
|
|
}
|
|
|
|
[Fact]
|
|
public void TestIntersectSegmentFromInsideBox() {
|
|
AABB box = new AABB(new Vector2(0, 0), new Vector2(8, 8));
|
|
var point = new Vector2(-4, 4);
|
|
var delta = new Vector2(32, 0);
|
|
Hit? maybeHit = box.IntersectSegment(point, delta);
|
|
|
|
Assert.NotNull(maybeHit);
|
|
Hit hit = (Hit) maybeHit;
|
|
|
|
Assert.Equal(box, hit.Collider);
|
|
Assert.Equal(0.0, hit.Time);
|
|
|
|
Assert.Equal(-4, hit.Position.X);
|
|
Assert.Equal(4, hit.Position.Y);
|
|
|
|
Assert.Equal(-delta.X, hit.Delta.X);
|
|
Assert.Equal(-delta.Y, hit.Delta.Y);
|
|
|
|
Assert.Equal(-1, hit.Normal.X);
|
|
Assert.Equal(0, hit.Normal.Y);
|
|
}
|
|
|
|
[Fact]
|
|
public void TestIntersectSegmentWithPadding() {
|
|
AABB box = new AABB(new Vector2(0, 0), new Vector2(8, 8));
|
|
var point = new Vector2(-16, 4);
|
|
var delta = new Vector2(32, 0);
|
|
int padding = 4;
|
|
Hit? maybeHit = box.IntersectSegment(point, delta, new Vector2(padding, padding));
|
|
|
|
Assert.NotNull(maybeHit);
|
|
Hit hit = (Hit) maybeHit;
|
|
|
|
Assert.Equal(box, hit.Collider);
|
|
Assert.Equal(0.125, hit.Time);
|
|
|
|
Assert.Equal(point.X + delta.X * hit.Time, hit.Position.X);
|
|
Assert.Equal(point.Y + delta.Y * hit.Time, hit.Position.Y);
|
|
|
|
Assert.Equal((1.0f - hit.Time) * -delta.X, hit.Delta.X);
|
|
Assert.Equal((1.0f - hit.Time) * -delta.Y, hit.Delta.Y);
|
|
|
|
Assert.Equal(-1, hit.Normal.X);
|
|
Assert.Equal(0, hit.Normal.Y);
|
|
}
|
|
|
|
[Fact]
|
|
public void TestIntersectSegmentFromTwoDirections() {
|
|
AABB box = new AABB(new Vector2(0, 0), new Vector2(32, 32));
|
|
var farPos = new Vector2(64, 0);
|
|
var farToNearDelta = new Vector2(-32, 0);
|
|
Assert.Null(box.IntersectSegment(farPos, farToNearDelta));
|
|
|
|
var nearPos = new Vector2(32, 0);
|
|
var nearToFarDelta = new Vector2(32, 0);
|
|
Assert.Null(box.IntersectSegment(nearPos, nearToFarDelta));
|
|
}
|
|
|
|
[Fact]
|
|
public void TestIntersectSegmentXAxisAligned() {
|
|
AABB box = new AABB(new Vector2(0, 0), new Vector2(16, 16));
|
|
var pos = new Vector2(-32, 0);
|
|
var delta = new Vector2(64, 0);
|
|
Hit? maybeHit = box.IntersectSegment(pos, delta);
|
|
|
|
Assert.NotNull(maybeHit);
|
|
Hit hit = (Hit) maybeHit;
|
|
|
|
Assert.Equal(0.25, hit.Time);
|
|
Assert.Equal(-1, hit.Normal.X);
|
|
Assert.Equal(0, hit.Normal.Y);
|
|
}
|
|
|
|
[Fact]
|
|
public void TestIntersectSegmentYAxisAligned() {
|
|
AABB box = new AABB(new Vector2(0, 0), new Vector2(16, 16));
|
|
var pos = new Vector2(0, -32);
|
|
var delta = new Vector2(0, 64);
|
|
Hit? maybeHit = box.IntersectSegment(pos, delta);
|
|
|
|
Assert.NotNull(maybeHit);
|
|
Hit hit = (Hit) maybeHit;
|
|
|
|
Assert.Equal(0.25, hit.Time);
|
|
Assert.Equal(0, hit.Normal.X);
|
|
Assert.Equal(-1, hit.Normal.Y);
|
|
}
|
|
}
|
|
} |