2013-11-05 19:31:33 +00:00
|
|
|
/**
|
2013-11-07 06:10:15 +00:00
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
2014-02-10 01:37:50 +00:00
|
|
|
* @author Adrien Brault <adrien.brault@gmail.com>
|
2014-02-05 05:54:25 +00:00
|
|
|
* @copyright 2014 Photon Storm Ltd.
|
2013-11-07 06:10:15 +00:00
|
|
|
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a new Polygon. You have to provide a list of points.
|
2014-03-23 07:59:28 +00:00
|
|
|
* This can be an array of Points that form the polygon, a flat array of numbers that will be interpreted as [x,y, x,y, ...],
|
2014-02-10 01:37:50 +00:00
|
|
|
* or the arguments passed can be all the points of the polygon e.g. `new Phaser.Polygon(new Phaser.Point(), new Phaser.Point(), ...)`, or the
|
|
|
|
* arguments passed can be flat x,y values e.g. `new Phaser.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are numbers.
|
2013-11-07 06:10:15 +00:00
|
|
|
*
|
2013-11-05 19:31:33 +00:00
|
|
|
* @class Phaser.Polygon
|
|
|
|
* @constructor
|
2014-09-16 16:35:08 +00:00
|
|
|
* @param {Phaser.Point[]|number[]} points - The array of Points.
|
2013-11-07 06:10:15 +00:00
|
|
|
*/
|
2013-11-05 19:25:06 +00:00
|
|
|
Phaser.Polygon = function (points) {
|
|
|
|
|
|
|
|
/**
|
2013-11-25 03:13:04 +00:00
|
|
|
* @property {number} type - The base object type.
|
|
|
|
*/
|
2013-11-05 19:25:06 +00:00
|
|
|
this.type = Phaser.POLYGON;
|
|
|
|
|
2014-10-22 22:52:46 +00:00
|
|
|
// If points isn't an array, use arguments as the array
|
|
|
|
if (!(points instanceof Array))
|
|
|
|
{
|
|
|
|
points = Array.prototype.slice.call(arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is a flat array of numbers, convert it to points
|
|
|
|
if (points[0] instanceof Phaser.Point)
|
|
|
|
{
|
|
|
|
var p = [];
|
|
|
|
|
|
|
|
for (var i = 0, il = points.length; i < il; i++)
|
|
|
|
{
|
|
|
|
p.push(points[i].x, points[i].y);
|
|
|
|
}
|
|
|
|
|
|
|
|
points = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {array} points - An array of Points that make up this Polygon.
|
|
|
|
*/
|
2014-08-21 21:46:44 +00:00
|
|
|
this.points = points;
|
2014-10-22 22:52:46 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @property {boolean} closed - Is the Polygon closed or not?
|
|
|
|
*/
|
|
|
|
this.closed = true;
|
|
|
|
|
2014-02-10 01:37:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Phaser.Polygon.prototype = {
|
|
|
|
|
|
|
|
/**
|
2014-08-21 21:45:10 +00:00
|
|
|
* Creates a copy of the given Polygon.
|
|
|
|
* This is a deep clone, the resulting copy contains new Phaser.Point objects
|
|
|
|
*
|
|
|
|
* @method Phaser.Polygon#clone
|
|
|
|
* @param {Phaser.Polygon} [output] Optional Polygon object. If given the values will be set into this object, otherwise a brand new Polygon object will be created and returned.
|
|
|
|
* @return {Phaser.Polygon} The new Polygon object.
|
|
|
|
*/
|
|
|
|
clone: function (output) {
|
2014-02-10 01:37:50 +00:00
|
|
|
|
2014-10-22 22:52:46 +00:00
|
|
|
var points = this.points.slice();
|
2014-02-10 01:37:50 +00:00
|
|
|
|
2014-08-21 21:45:10 +00:00
|
|
|
if (typeof output === "undefined" || output === null)
|
|
|
|
{
|
|
|
|
output = new Phaser.Polygon(points);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
output.setTo(points);
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
2014-02-10 01:37:50 +00:00
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks whether the x and y coordinates are contained within this polygon.
|
|
|
|
*
|
|
|
|
* @method Phaser.Polygon#contains
|
|
|
|
* @param {number} x - The X value of the coordinate to test.
|
|
|
|
* @param {number} y - The Y value of the coordinate to test.
|
|
|
|
* @return {boolean} True if the coordinates are within this polygon, otherwise false.
|
|
|
|
*/
|
|
|
|
contains: function (x, y) {
|
|
|
|
|
|
|
|
// use some raycasting to test hits https://github.com/substack/point-in-polygon/blob/master/index.js
|
2014-10-22 22:52:46 +00:00
|
|
|
|
|
|
|
var length = this.points.length / 2;
|
|
|
|
|
|
|
|
for (var i = 0, j = length - 1; i < length; j = i++)
|
2014-02-10 01:37:50 +00:00
|
|
|
{
|
2014-10-22 22:52:46 +00:00
|
|
|
var xi = this.points[i * 2].x;
|
|
|
|
var yi = this.points[i * 2 + 1].y;
|
|
|
|
var xj = this.points[j * 2].x;
|
|
|
|
var yj = this.points[j * 2 + 1].y;
|
2014-02-10 01:37:50 +00:00
|
|
|
|
|
|
|
var intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
|
|
|
|
|
|
|
if (intersect)
|
|
|
|
{
|
2014-10-28 13:04:33 +00:00
|
|
|
return true;
|
2014-02-10 01:37:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-28 13:04:33 +00:00
|
|
|
return false;
|
2014-02-10 01:37:50 +00:00
|
|
|
|
2014-08-21 21:45:10 +00:00
|
|
|
},
|
|
|
|
|
2014-10-22 22:52:46 +00:00
|
|
|
/**
|
|
|
|
* Sets this Polygon to the given points.
|
|
|
|
*
|
|
|
|
* @method Phaser.Polygon#setTo
|
|
|
|
* @param {Phaser.Point[]|number[]} points - The array of Points.
|
|
|
|
* @return {boolean} True if the coordinates are within this polygon, otherwise false.
|
|
|
|
*/
|
|
|
|
setTo: function (points) {
|
|
|
|
|
|
|
|
// If points isn't an array, use arguments as the array
|
|
|
|
if (!(points instanceof Array))
|
|
|
|
{
|
|
|
|
points = Array.prototype.slice.call(arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is a flat array of numbers, convert it to points
|
|
|
|
if (points[0] instanceof Phaser.Point)
|
|
|
|
{
|
|
|
|
var p = [];
|
|
|
|
|
|
|
|
for (var i = 0, il = points.length; i < il; i++)
|
|
|
|
{
|
|
|
|
p.push(points[i].x, points[i].y);
|
|
|
|
}
|
|
|
|
|
|
|
|
points = p;
|
|
|
|
}
|
2014-08-21 21:45:10 +00:00
|
|
|
|
2014-08-21 21:50:09 +00:00
|
|
|
this.points = points;
|
2014-08-21 21:45:10 +00:00
|
|
|
|
|
|
|
return this;
|
|
|
|
|
2014-02-10 01:37:50 +00:00
|
|
|
}
|
|
|
|
|
2013-11-05 19:25:06 +00:00
|
|
|
};
|
|
|
|
|
2014-02-10 01:37:50 +00:00
|
|
|
Phaser.Polygon.prototype.constructor = Phaser.Polygon;
|
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
/*
|
2014-05-13 23:04:31 +00:00
|
|
|
* Sets and modifies the points of this polygon.
|
|
|
|
*
|
|
|
|
* @name Phaser.Polygon#points
|
|
|
|
* @property {array<Phaser.Point>|array<number>} points - The array of vertex points
|
|
|
|
*/
|
2014-05-02 17:30:49 +00:00
|
|
|
Object.defineProperty(Phaser.Polygon.prototype, 'points', {
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
get: function() {
|
|
|
|
return this._points;
|
|
|
|
},
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
set: function(points) {
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
//if points isn't an array, use arguments as the array
|
|
|
|
if (!(points instanceof Array))
|
|
|
|
{
|
|
|
|
points = Array.prototype.slice.call(arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
//if this is a flat array of numbers, convert it to points
|
|
|
|
if (typeof points[0] === 'number')
|
|
|
|
{
|
|
|
|
var p = [];
|
|
|
|
|
|
|
|
for (var i = 0, len = points.length; i < len; i += 2)
|
|
|
|
{
|
|
|
|
p.push(new Phaser.Point(points[i], points[i + 1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
points = p;
|
|
|
|
}
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
this._points = points;
|
|
|
|
}
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the area of the polygon.
|
|
|
|
*
|
2014-10-22 22:52:46 +00:00
|
|
|
* @name Phaser.Polygon#area
|
2014-05-02 17:30:49 +00:00
|
|
|
* @readonly
|
|
|
|
*/
|
|
|
|
Object.defineProperty(Phaser.Polygon.prototype, 'area', {
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
get: function() {
|
2014-05-13 23:04:31 +00:00
|
|
|
|
|
|
|
var p1;
|
|
|
|
var p2;
|
|
|
|
var avgHeight;
|
|
|
|
var width;
|
|
|
|
var i;
|
|
|
|
var y0 = Number.MAX_VALUE;
|
|
|
|
var area = 0;
|
2014-05-02 17:30:49 +00:00
|
|
|
|
|
|
|
// Find lowest boundary
|
2014-05-13 23:04:31 +00:00
|
|
|
for (i = 0; i < this.points.length; i++)
|
|
|
|
{
|
|
|
|
if (this.points[i].y < y0)
|
|
|
|
{
|
2014-05-02 17:30:49 +00:00
|
|
|
y0 = this.points[i].y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-13 23:04:31 +00:00
|
|
|
for (i = 0; i< this.points.length; i++)
|
|
|
|
{
|
2014-05-02 17:30:49 +00:00
|
|
|
p1 = this.points[i];
|
2014-05-13 23:04:31 +00:00
|
|
|
|
|
|
|
if (i === this.points.length - 1)
|
|
|
|
{
|
2014-05-02 17:30:49 +00:00
|
|
|
p2 = this.points[0];
|
2014-05-13 23:04:31 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-02 17:30:49 +00:00
|
|
|
p2 = this.points[i+1];
|
|
|
|
}
|
|
|
|
|
|
|
|
avgHeight = ((p1.y - y0) + (p2.y - y0)) / 2;
|
|
|
|
width = p1.x - p2.x;
|
|
|
|
area += avgHeight * width;
|
|
|
|
}
|
|
|
|
|
|
|
|
return area;
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
}
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-05-02 17:30:49 +00:00
|
|
|
});
|
2014-05-13 23:04:31 +00:00
|
|
|
|
2014-02-10 01:37:50 +00:00
|
|
|
// Because PIXI uses its own Polygon, we'll replace it with ours to avoid duplicating code or confusion.
|
2014-10-22 22:52:46 +00:00
|
|
|
// PIXI.Polygon = Phaser.Polygon;
|