phaser/src/geom/polygon/Polygon.js

229 lines
6.9 KiB
JavaScript
Raw Normal View History

2018-02-12 16:01:20 +00:00
/**
* @author Richard Davey <rich@photonstorm.com>
2020-01-15 12:07:09 +00:00
* @copyright 2020 Photon Storm Ltd.
2019-05-10 15:15:04 +00:00
* @license {@link https://opensource.org/licenses/MIT|MIT License}
2018-02-12 16:01:20 +00:00
*/
var Class = require('../../utils/Class');
var Contains = require('./Contains');
2018-09-01 00:30:36 +00:00
var GetPoints = require('./GetPoints');
2019-07-18 09:36:11 +00:00
var GEOM_CONST = require('../const');
2017-01-07 01:06:57 +00:00
2018-02-07 15:27:21 +00:00
/**
* @classdesc
2018-12-03 15:16:23 +00:00
* A Polygon object
*
* The polygon is a closed shape consists of a series of connected straight lines defined by list of ordered points.
2020-10-15 11:01:13 +00:00
* Several formats are supported to define the list of points, check the setTo method for details.
2018-12-03 15:16:23 +00:00
* This is a geometry object allowing you to define and inspect the shape.
* It is not a Game Object, in that you cannot add it to the display list, and it has no texture.
* To render a Polygon you should look at the capabilities of the Graphics class.
2018-02-07 15:27:21 +00:00
*
* @class Polygon
2018-10-10 09:49:13 +00:00
* @memberof Phaser.Geom
2018-02-07 15:27:21 +00:00
* @constructor
* @since 3.0.0
*
2020-11-20 16:30:05 +00:00
* @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - List of points defining the perimeter of this Polygon. Several formats are supported:
2018-12-03 15:16:23 +00:00
* - A string containing paired x y values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'`
* - An array of Point objects: `[new Phaser.Point(x1, y1), ...]`
* - An array of objects with public x y properties: `[obj1, obj2, ...]`
* - An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]`
* - An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]`
2018-02-07 15:27:21 +00:00
*/
var Polygon = new Class({
initialize:
2017-01-07 01:06:57 +00:00
function Polygon (points)
2017-01-07 01:06:57 +00:00
{
2019-07-18 09:36:11 +00:00
/**
* The geometry constant type of this object: `GEOM_CONST.POLYGON`.
* Used for fast type comparisons.
*
* @name Phaser.Geom.Polygon#type
* @type {integer}
* @readonly
* @since 3.19.0
*/
this.type = GEOM_CONST.POLYGON;
2018-01-26 13:14:41 +00:00
/**
2018-02-07 15:27:21 +00:00
* The area of this Polygon.
2018-01-26 13:14:41 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Geom.Polygon#area
* @type {number}
2018-01-26 13:14:41 +00:00
* @default 0
* @since 3.0.0
*/
this.area = 0;
2017-01-07 01:06:57 +00:00
2018-01-26 13:14:41 +00:00
/**
2018-02-07 15:27:21 +00:00
* An array of number pair objects that make up this polygon. I.e. [ {x,y}, {x,y}, {x,y} ]
2018-01-26 13:14:41 +00:00
*
2018-02-07 15:27:21 +00:00
* @name Phaser.Geom.Polygon#points
* @type {Phaser.Geom.Point[]}
2018-01-26 13:14:41 +00:00
* @since 3.0.0
*/
this.points = [];
2017-01-07 01:06:57 +00:00
if (points)
{
this.setTo(points);
}
},
2017-01-07 01:06:57 +00:00
2018-01-26 13:14:41 +00:00
/**
2018-09-24 22:20:43 +00:00
* Check to see if the Polygon contains the given x / y coordinates.
2018-01-26 13:14:41 +00:00
*
2018-02-07 15:27:21 +00:00
* @method Phaser.Geom.Polygon#contains
2018-01-26 13:14:41 +00:00
* @since 3.0.0
*
2018-09-24 22:20:43 +00:00
* @param {number} x - The x coordinate to check within the polygon.
* @param {number} y - The y coordinate to check within the polygon.
2018-01-26 13:14:41 +00:00
*
2018-09-24 22:20:43 +00:00
* @return {boolean} `true` if the coordinates are within the polygon, otherwise `false`.
2018-01-26 13:14:41 +00:00
*/
contains: function (x, y)
{
return Contains(this, x, y);
},
2017-01-07 01:06:57 +00:00
/**
* Sets this Polygon to the given points.
*
* The points can be set from a variety of formats:
*
* - A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'`
2017-01-07 01:06:57 +00:00
* - An array of Point objects: `[new Phaser.Point(x1, y1), ...]`
* - An array of objects with public x/y properties: `[obj1, obj2, ...]`
* - An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]`
* - An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]`
*
* `setTo` may also be called without any arguments to remove all points.
2018-01-26 13:14:41 +00:00
*
2018-02-07 15:27:21 +00:00
* @method Phaser.Geom.Polygon#setTo
2018-01-26 13:14:41 +00:00
* @since 3.0.0
*
2020-11-20 16:30:05 +00:00
* @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - Points defining the perimeter of this polygon. Please check function description above for the different supported formats.
2018-01-26 13:14:41 +00:00
*
* @return {this} This Polygon object.
2018-01-26 13:14:41 +00:00
*/
2017-01-07 01:06:57 +00:00
setTo: function (points)
{
this.area = 0;
this.points = [];
2017-01-07 01:06:57 +00:00
if (typeof points === 'string')
{
points = points.split(' ');
}
2017-01-07 01:06:57 +00:00
if (!Array.isArray(points))
{
return this;
}
var p;
var y0 = Number.MAX_VALUE;
2017-01-07 01:06:57 +00:00
// The points argument is an array, so iterate through it
for (var i = 0; i < points.length; i++)
{
p = { x: 0, y: 0 };
if (typeof points[i] === 'number' || typeof points[i] === 'string')
2017-01-07 01:06:57 +00:00
{
p.x = parseFloat(points[i]);
p.y = parseFloat(points[i + 1]);
2017-01-07 01:06:57 +00:00
i++;
}
else if (Array.isArray(points[i]))
2017-01-07 01:06:57 +00:00
{
// An array of arrays?
p.x = points[i][0];
p.y = points[i][1];
}
else
{
p.x = points[i].x;
p.y = points[i].y;
}
this.points.push(p);
2017-01-07 01:06:57 +00:00
// Lowest boundary
if (p.y < y0)
{
y0 = p.y;
}
}
this.calculateArea(y0);
return this;
},
/**
* Calculates the area of the Polygon. This is available in the property Polygon.area
2018-01-26 13:14:41 +00:00
*
2018-02-07 15:27:21 +00:00
* @method Phaser.Geom.Polygon#calculateArea
2018-01-26 13:14:41 +00:00
* @since 3.0.0
*
2018-09-24 22:20:43 +00:00
* @return {number} The area of the polygon.
2018-01-26 13:14:41 +00:00
*/
2018-02-07 15:27:21 +00:00
calculateArea: function ()
2017-01-07 01:06:57 +00:00
{
if (this.points.length < 3)
{
this.area = 0;
return this.area;
}
var sum = 0;
2017-01-07 01:06:57 +00:00
var p1;
var p2;
for (var i = 0; i < this.points.length - 1; i++)
2017-01-07 01:06:57 +00:00
{
p1 = this.points[i];
p2 = this.points[i + 1];
2017-01-07 01:06:57 +00:00
sum += (p2.x - p1.x) * (p1.y + p2.y);
2017-01-07 01:06:57 +00:00
}
p1 = this.points[0];
p2 = this.points[this.points.length - 1];
sum += (p1.x - p2.x) * (p2.y + p1.y);
this.area = -sum * 0.5;
2017-01-07 01:06:57 +00:00
return this.area;
2018-09-01 00:30:36 +00:00
},
2018-09-01 09:19:38 +00:00
/**
* Returns an array of Point objects containing the coordinates of the points around the perimeter of the Polygon,
* based on the given quantity or stepRate values.
*
* @method Phaser.Geom.Polygon#getPoints
* @since 3.12.0
*
2020-01-03 12:21:50 +00:00
* @generic {Phaser.Geom.Point[]} O - [output,$return]
*
2018-09-01 09:19:38 +00:00
* @param {integer} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead.
* @param {number} [stepRate] - Sets the quantity by getting the perimeter of the Polygon and dividing it by the stepRate.
2020-01-03 12:21:50 +00:00
* @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created.
2018-09-01 09:19:38 +00:00
*
2020-01-03 12:21:50 +00:00
* @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the perimeter of the Polygon.
2018-09-01 09:19:38 +00:00
*/
2018-09-01 00:30:36 +00:00
getPoints: function (quantity, step, output)
{
return GetPoints(this, quantity, step, output);
2017-01-07 01:06:57 +00:00
}
});
2017-01-06 23:59:45 +00:00
module.exports = Polygon;