-
Notifications
You must be signed in to change notification settings - Fork 7.1k
/
Polygon.js
228 lines (198 loc) · 6.91 KB
/
Polygon.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2020 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Class = require('../../utils/Class');
var Contains = require('./Contains');
var GetPoints = require('./GetPoints');
var GEOM_CONST = require('../const');
/**
* @classdesc
* A Polygon object
*
* The polygon is a closed shape consists of a series of connected straight lines defined by list of ordered points.
* Several formats are supported to define the list of points, check the setTo method for details.
* 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.
*
* @class Polygon
* @memberof Phaser.Geom
* @constructor
* @since 3.0.0
*
* @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - List of points defining the perimeter of this Polygon. Several formats are supported:
* - 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], ...]`
*/
var Polygon = new Class({
initialize:
function Polygon (points)
{
/**
* The geometry constant type of this object: `GEOM_CONST.POLYGON`.
* Used for fast type comparisons.
*
* @name Phaser.Geom.Polygon#type
* @type {number}
* @readonly
* @since 3.19.0
*/
this.type = GEOM_CONST.POLYGON;
/**
* The area of this Polygon.
*
* @name Phaser.Geom.Polygon#area
* @type {number}
* @default 0
* @since 3.0.0
*/
this.area = 0;
/**
* An array of number pair objects that make up this polygon. I.e. [ {x,y}, {x,y}, {x,y} ]
*
* @name Phaser.Geom.Polygon#points
* @type {Phaser.Geom.Point[]}
* @since 3.0.0
*/
this.points = [];
if (points)
{
this.setTo(points);
}
},
/**
* Check to see if the Polygon contains the given x / y coordinates.
*
* @method Phaser.Geom.Polygon#contains
* @since 3.0.0
*
* @param {number} x - The x coordinate to check within the polygon.
* @param {number} y - The y coordinate to check within the polygon.
*
* @return {boolean} `true` if the coordinates are within the polygon, otherwise `false`.
*/
contains: function (x, y)
{
return Contains(this, x, y);
},
/**
* 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'`
* - 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.
*
* @method Phaser.Geom.Polygon#setTo
* @since 3.0.0
*
* @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.
*
* @return {this} This Polygon object.
*/
setTo: function (points)
{
this.area = 0;
this.points = [];
if (typeof points === 'string')
{
points = points.split(' ');
}
if (!Array.isArray(points))
{
return this;
}
var p;
var y0 = Number.MAX_VALUE;
// 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')
{
p.x = parseFloat(points[i]);
p.y = parseFloat(points[i + 1]);
i++;
}
else if (Array.isArray(points[i]))
{
// 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);
// 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
*
* @method Phaser.Geom.Polygon#calculateArea
* @since 3.0.0
*
* @return {number} The area of the polygon.
*/
calculateArea: function ()
{
if (this.points.length < 3)
{
this.area = 0;
return this.area;
}
var sum = 0;
var p1;
var p2;
for (var i = 0; i < this.points.length - 1; i++)
{
p1 = this.points[i];
p2 = this.points[i + 1];
sum += (p2.x - p1.x) * (p1.y + p2.y);
}
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;
return this.area;
},
/**
* 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
*
* @generic {Phaser.Geom.Point[]} O - [output,$return]
*
* @param {number} 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.
* @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created.
*
* @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the perimeter of the Polygon.
*/
getPoints: function (quantity, step, output)
{
return GetPoints(this, quantity, step, output);
}
});
module.exports = Polygon;