phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.
214 lines (165 loc) • 7.08 kB
JavaScript
var PerimeterPoint = require('../../../src/geom/rectangle/PerimeterPoint');
var Vector2 = require('../../../src/math/Vector2');
describe('Phaser.Geom.Rectangle.PerimeterPoint', function ()
{
var rect;
beforeEach(function ()
{
// 200x100 rectangle at (0,0): centerX=100, centerY=50
rect = { x: 0, y: 0, width: 200, height: 100, centerX: 100, centerY: 50 };
});
it('should return a Vector2 when no out parameter is given', function ()
{
var result = PerimeterPoint(rect, 0);
expect(result).toBeInstanceOf(Vector2);
});
it('should use the provided out object', function ()
{
var out = new Vector2();
var result = PerimeterPoint(rect, 0, out);
expect(result).toBe(out);
});
it('should return the right-center point at 0 degrees', function ()
{
var result = PerimeterPoint(rect, 0);
expect(result.x).toBeCloseTo(200, 5);
expect(result.y).toBeCloseTo(50, 5);
});
it('should return the bottom-center point at 90 degrees', function ()
{
var result = PerimeterPoint(rect, 90);
expect(result.x).toBeCloseTo(100, 5);
expect(result.y).toBeCloseTo(100, 5);
});
it('should return the left-center point at 180 degrees', function ()
{
var result = PerimeterPoint(rect, 180);
expect(result.x).toBeCloseTo(0, 5);
expect(result.y).toBeCloseTo(50, 5);
});
it('should return the top-center point at 270 degrees', function ()
{
var result = PerimeterPoint(rect, 270);
expect(result.x).toBeCloseTo(100, 5);
expect(result.y).toBeCloseTo(0, 5);
});
it('should return the top-center point at -90 degrees', function ()
{
var result = PerimeterPoint(rect, -90);
expect(result.x).toBeCloseTo(100, 5);
expect(result.y).toBeCloseTo(0, 5);
});
it('should return the right-center point at 360 degrees', function ()
{
var result = PerimeterPoint(rect, 360);
expect(result.x).toBeCloseTo(200, 5);
expect(result.y).toBeCloseTo(50, 5);
});
it('should return the bottom-right corner for a square at 45 degrees', function ()
{
var square = { width: 100, height: 100, centerX: 50, centerY: 50 };
var result = PerimeterPoint(square, 45);
expect(result.x).toBeCloseTo(100, 5);
expect(result.y).toBeCloseTo(100, 5);
});
it('should return the bottom-left corner for a square at 135 degrees', function ()
{
var square = { width: 100, height: 100, centerX: 50, centerY: 50 };
var result = PerimeterPoint(square, 135);
expect(result.x).toBeCloseTo(0, 5);
expect(result.y).toBeCloseTo(100, 5);
});
it('should return the top-left corner for a square at 225 degrees', function ()
{
var square = { width: 100, height: 100, centerX: 50, centerY: 50 };
var result = PerimeterPoint(square, 225);
expect(result.x).toBeCloseTo(0, 5);
expect(result.y).toBeCloseTo(0, 5);
});
it('should return the top-right corner for a square at 315 degrees', function ()
{
var square = { width: 100, height: 100, centerX: 50, centerY: 50 };
var result = PerimeterPoint(square, 315);
expect(result.x).toBeCloseTo(100, 5);
expect(result.y).toBeCloseTo(0, 5);
});
it('should clamp to the horizontal edge for shallow angles on a wide rectangle', function ()
{
// Wide rectangle: width=400, height=100, so half-width=200, half-height=50
// At 10 degrees the ray hits the right edge before the top/bottom edge
var wide = { width: 400, height: 100, centerX: 200, centerY: 50 };
var result = PerimeterPoint(wide, 10);
expect(result.x).toBeCloseTo(400, 5);
expect(result.y).toBeCloseTo(50 + Math.tan(10 * Math.PI / 180) * 200, 5);
});
it('should clamp to the vertical edge for steep angles on a wide rectangle', function ()
{
// At 80 degrees the ray hits the bottom edge before the left/right edge
var wide = { width: 400, height: 100, centerX: 200, centerY: 50 };
var result = PerimeterPoint(wide, 80);
expect(result.y).toBeCloseTo(100, 5);
});
it('should work with a rectangle offset from the origin', function ()
{
var offset = { width: 200, height: 100, centerX: 300, centerY: 200 };
var result = PerimeterPoint(offset, 0);
expect(result.x).toBeCloseTo(400, 5);
expect(result.y).toBeCloseTo(200, 5);
});
it('should work with a rectangle offset from the origin at 90 degrees', function ()
{
var offset = { width: 200, height: 100, centerX: 300, centerY: 200 };
var result = PerimeterPoint(offset, 90);
expect(result.x).toBeCloseTo(300, 5);
expect(result.y).toBeCloseTo(250, 5);
});
it('should populate the out object x and y properties', function ()
{
var out = { x: 0, y: 0 };
PerimeterPoint(rect, 0, out);
expect(out.x).toBeCloseTo(200, 5);
expect(out.y).toBeCloseTo(50, 5);
});
it('should return a point on the right edge for small positive angles', function ()
{
var result = PerimeterPoint(rect, 26.565);
// tan(26.565°) ≈ 0.5, so dy/dx = 0.5, dx = 100 (half-width), dy = 50 (half-height) — hits corner
expect(result.x).toBeCloseTo(200, 0);
});
it('should return a point on the bottom edge for large positive angles below 90', function ()
{
var result = PerimeterPoint(rect, 63.435);
// tan(63.435°) ≈ 2, dy/dx = 2, half-height=50, half-width=100; ray hits bottom edge
expect(result.y).toBeCloseTo(100, 0);
});
it('should handle floating point angle values', function ()
{
var result = PerimeterPoint(rect, 45.5);
expect(typeof result.x).toBe('number');
expect(typeof result.y).toBe('number');
expect(isNaN(result.x)).toBe(false);
expect(isNaN(result.y)).toBe(false);
});
it('should return symmetric points for opposite angles', function ()
{
var r1 = PerimeterPoint(rect, 45);
var r2 = PerimeterPoint(rect, 225);
// Opposite angles should produce points mirrored through the center
expect(r1.x + r2.x).toBeCloseTo(rect.centerX * 2, 5);
expect(r1.y + r2.y).toBeCloseTo(rect.centerY * 2, 5);
});
it('should return symmetric points for 0 and 180 degrees', function ()
{
var r1 = PerimeterPoint(rect, 0);
var r2 = PerimeterPoint(rect, 180);
expect(r1.x + r2.x).toBeCloseTo(rect.centerX * 2, 5);
expect(r1.y + r2.y).toBeCloseTo(rect.centerY * 2, 5);
});
it('should return symmetric points for 90 and 270 degrees', function ()
{
var r1 = PerimeterPoint(rect, 90);
var r2 = PerimeterPoint(rect, 270);
expect(r1.x + r2.x).toBeCloseTo(rect.centerX * 2, 5);
expect(r1.y + r2.y).toBeCloseTo(rect.centerY * 2, 5);
});
});