]> git.proxmox.com Git - extjs.git/blame - extjs/packages/charts/src/draw/Point.js
add extjs 6.0.1 sources
[extjs.git] / extjs / packages / charts / src / draw / Point.js
CommitLineData
6527f429
DM
1/**\r
2 * A helper class to facilitate common operations on points and vectors.\r
3 */\r
4Ext.define('Ext.draw.Point', {\r
5\r
6 requires: [\r
7 'Ext.draw.Draw',\r
8 'Ext.draw.Matrix'\r
9 ],\r
10\r
11 isPoint: true,\r
12\r
13 x: 0,\r
14 y: 0,\r
15\r
16 length: 0,\r
17 angle: 0,\r
18\r
19 angleUnits: 'degrees',\r
20\r
21 statics: {\r
22 /**\r
23 * @method\r
24 * @static\r
25 * Creates a flyweight Ext.draw.Point instance.\r
26 * Takes the same parameters as the {@link Ext.draw.Point#constructor}.\r
27 * Do not hold the instance of the flyweight point.\r
28 *\r
29 * @param point {Number/Number[]/Object/Ext.draw.Point}\r
30 * @return {Ext.draw.Point}\r
31 */\r
32 fly: (function () {\r
33 var point = null;\r
34 return function (x, y) {\r
35 if (!point) {\r
36 point = new Ext.draw.Point();\r
37 }\r
38 point.constructor(x, y);\r
39 return point;\r
40 }\r
41 })()\r
42 },\r
43\r
44 /**\r
45 * Creates a point.\r
46 *\r
47 * new Ext.draw.Point(3, 4);\r
48 * new Ext.draw.Point(3); // both x and y equal 3\r
49 * new Ext.draw.Point([3, 4]);\r
50 * new Ext.draw.Point({x: 3, y: 4});\r
51 * new Ext.draw.Point(p); // where `p` is a Ext.draw.Point instance.\r
52 *\r
53 * @param point {Number/Number[]/Object/Ext.draw.Point}\r
54 */\r
55 constructor: function (x, y) {\r
56 var me = this;\r
57\r
58 if (typeof x === 'number') {\r
59 me.x = x;\r
60 if (typeof y === 'number') {\r
61 me.y = y;\r
62 } else {\r
63 me.y = x;\r
64 }\r
65 } else if (Ext.isArray(x)) {\r
66 me.x = x[0];\r
67 me.y = x[1];\r
68 } else if (x) {\r
69 me.x = x.x;\r
70 me.y = x.y;\r
71 }\r
72\r
73 me.calculatePolar();\r
74 },\r
75\r
76 calculateCartesian: function () {\r
77 var me = this,\r
78 length = me.length,\r
79 angle = me.angle;\r
80\r
81 if (me.angleUnits === 'degrees') {\r
82 angle = Ext.draw.Draw.rad(angle);\r
83 }\r
84 me.x = Math.cos(angle) * length;\r
85 me.y = Math.sin(angle) * length;\r
86 },\r
87\r
88 calculatePolar: function () {\r
89 var me = this,\r
90 x = me.x,\r
91 y = me.y;\r
92\r
93 me.length = Math.sqrt(x * x + y * y);\r
94 me.angle = Math.atan2(y, x);\r
95 if (me.angleUnits === 'degrees') {\r
96 me.angle = Ext.draw.Draw.degrees(me.angle);\r
97 }\r
98 },\r
99\r
100 /**\r
101 * Sets the x-coordinate of the point.\r
102 * @param x {Number}\r
103 */\r
104 setX: function (x) {\r
105 this.x = x;\r
106 this.calculatePolar();\r
107 },\r
108\r
109 /**\r
110 * Sets the y-coordinate of the point.\r
111 * @param y {Number}\r
112 */\r
113 setY: function (y) {\r
114 this.y = y;\r
115 this.calculatePolar();\r
116 },\r
117\r
118 /**\r
119 * Sets coordinates of the point.\r
120 * Takes the same parameters as the {@link #constructor}.\r
121 * @param point {Number/Number[]/Object/Ext.draw.Point}\r
122 */\r
123 set: function (x, y) {\r
124 this.constructor(x, y);\r
125 },\r
126\r
127 /**\r
128 * Sets the angle of the vector (measured from the x-axis to the vector)\r
129 * without changing its length.\r
130 * @param angle {Number}\r
131 */\r
132 setAngle: function (angle) {\r
133 this.angle = angle;\r
134 this.calculateCartesian();\r
135 },\r
136\r
137 /**\r
138 * Sets the length of the vector without changing its angle.\r
139 * @param length {Number}\r
140 */\r
141 setLength: function (length) {\r
142 this.length = length;\r
143 this.calculateCartesian();\r
144 },\r
145\r
146 /**\r
147 * Sets both the angle and the length of the vector.\r
148 * A point can be thought of as a vector pointing from the origin to the point's location.\r
149 * This can also be interpreted as setting coordinates of a point in the polar\r
150 * coordinate system.\r
151 * @param angle {Number}\r
152 * @param length {Number}\r
153 */\r
154 setPolar: function (angle, length) {\r
155 this.angle = angle;\r
156 this.length = length;\r
157 this.calculateCartesian();\r
158 },\r
159\r
160 /**\r
161 * Returns a copy of the point.\r
162 * @return {Ext.draw.Point}\r
163 */\r
164 clone: function () {\r
165 return new Ext.draw.Point(this.x, this.y);\r
166 },\r
167\r
168 /**\r
169 * Adds another vector to this one and returns the resulting vector\r
170 * without changing this vector.\r
171 * @param point {Number/Number[]/Object/Ext.draw.Point}\r
172 * @return {Ext.draw.Point}\r
173 */\r
174 add: function (x, y) {\r
175 var fly = Ext.draw.Point.fly(x, y);\r
176 return new Ext.draw.Point(this.x + fly.x, this.y + fly.y);\r
177 },\r
178\r
179 /**\r
180 * Subtracts another vector from this one and returns the resulting vector\r
181 * without changing this vector.\r
182 * @param point {Number/Number[]/Object/Ext.draw.Point}\r
183 * @return {Ext.draw.Point}\r
184 */\r
185 sub: function (x, y) {\r
186 var fly = Ext.draw.Point.fly(x, y);\r
187 return new Ext.draw.Point(this.x - fly.x, this.y - fly.y);\r
188 },\r
189\r
190 /**\r
191 * Returns the result of scalar multiplication of this vector by the given factor.\r
192 * This vector is not modified.\r
193 * @param n {Number} The factor.\r
194 * @return {Ext.draw.Point}\r
195 */\r
196 mul: function (n) {\r
197 return new Ext.draw.Point(this.x * n, this.y * n);\r
198 },\r
199\r
200 /**\r
201 * Returns a vector which coordinates are the result of division of this vector's\r
202 * coordinates by the given number. This vector is not modified.\r
203 * This vector is not modified.\r
204 * @param n {Number} The denominator.\r
205 * @return {Ext.draw.Point}\r
206 */\r
207 div: function (n) {\r
208 return new Ext.draw.Point(this.x / n, this.y / n);\r
209 },\r
210\r
211 /**\r
212 * Returns the dot product of this vector and the given vector.\r
213 * @param point {Number/Number[]/Object/Ext.draw.Point}\r
214 * @return {Number}\r
215 */\r
216 dot: function (x, y) {\r
217 var fly = Ext.draw.Point.fly(x, y);\r
218 return this.x * fly.x + this.y * fly.y;\r
219 },\r
220\r
221 /**\r
222 * Checks whether coordinates of the point match those of the point provided.\r
223 * @param point {Number/Number[]/Object/Ext.draw.Point}\r
224 * @return {Boolean}\r
225 */\r
226 equals: function (x, y) {\r
227 var fly = Ext.draw.Point.fly(x, y);\r
228 return this.x === fly.x && this.y === fly.y;\r
229 },\r
230\r
231 /**\r
232 * Rotates the point by the given angle. This point is not modified.\r
233 * @param angle {Number} The rotation angle.\r
234 * @param center {Ext.draw.Point} The center of rotation (optional). Defaults to origin.\r
235 * @return {Ext.draw.Point} The rotated point.\r
236 */\r
237 rotate: function (angle, center) {\r
238 var sin, cos,\r
239 cx, cy,\r
240 point;\r
241\r
242 if (this.angleUnits === 'degrees') {\r
243 angle = Ext.draw.Draw.rad(angle);\r
244 sin = Math.sin(angle);\r
245 cos = Math.cos(angle);\r
246 }\r
247 if (center) {\r
248 cx = center.x;\r
249 cy = center.y;\r
250 } else {\r
251 cx = 0;\r
252 cy = 0;\r
253 }\r
254 point = Ext.draw.Matrix.fly([\r
255 cos, sin,\r
256 -sin, cos,\r
257 cx - cos * cx + cy * sin,\r
258 cy - cos * cy + cx * -sin\r
259 ]).transformPoint(this);\r
260\r
261 return new Ext.draw.Point(point);\r
262 },\r
263\r
264 /**\r
265 * Transforms the point from one coordinate system to another\r
266 * using the transformation matrix provided. This point is not modified.\r
267 * @param matrix {Ext.draw.Matrix/Number[]} A trasformation matrix or its elements.\r
268 * @return {Ext.draw.Point}\r
269 */\r
270 transform: function (matrix) {\r
271 if (matrix && matrix.isMatrix) {\r
272 return new Ext.draw.Point(matrix.transformPoint(this));\r
273 } else if (arguments.length === 6) {\r
274 return new Ext.draw.Point(Ext.draw.Matrix.fly(arguments).transformPoint(this));\r
275 } else {\r
276 Ext.raise("Invalid parameters.");\r
277 }\r
278 },\r
279\r
280 /**\r
281 * Returns a new point with rounded x and y values. This point is not modified.\r
282 * @return {Ext.draw.Point}\r
283 */\r
284 round: function () {\r
285 return new Ext.draw.Point(\r
286 Math.round(this.x),\r
287 Math.round(this.y)\r
288 );\r
289 },\r
290\r
291 /**\r
292 * Returns a new point with ceiled x and y values. This point is not modified.\r
293 * @return {Ext.draw.Point}\r
294 */\r
295 ceil: function () {\r
296 return new Ext.draw.Point(\r
297 Math.ceil(this.x),\r
298 Math.ceil(this.y)\r
299 );\r
300 },\r
301\r
302 /**\r
303 * Returns a new point with floored x and y values. This point is not modified.\r
304 * @return {Ext.draw.Point}\r
305 */\r
306 floor: function () {\r
307 return new Ext.draw.Point(\r
308 Math.floor(this.x),\r
309 Math.floor(this.y)\r
310 );\r
311 },\r
312\r
313 /**\r
314 * Returns a new point with absolute values of the x and y values of this point.\r
315 * This point is not modified.\r
316 * @return {Ext.draw.Point}\r
317 */\r
318 abs: function (x, y) {\r
319 return new Ext.draw.Point(\r
320 Math.abs(this.x),\r
321 Math.abs(this.y)\r
322 );\r
323 },\r
324\r
325 /**\r
326 * Normalizes the vector by changing its length to 1 without changing its angle.\r
327 * The returned result is a normalized vector. This vector is not modified.\r
328 * @param length {Number=1} The length of the normalized vector. Defaults to 1.\r
329 * @return {Ext.draw.Point}\r
330 */\r
331 normalize: function (length) {\r
332 var x = this.x,\r
333 y = this.y,\r
334 nx, ny, tg;\r
335\r
336 length = length || 1;\r
337\r
338 if (x === 0) {\r
339 nx = 0;\r
340 ny = length * Ext.Number.sign(y);\r
341 } else {\r
342 tg = y/x;\r
343 nx = length / Math.sqrt(1 + tg * tg);\r
344 ny = nx * tg;\r
345 }\r
346 return new Ext.draw.Point(nx, ny);\r
347 },\r
348\r
349 /**\r
350 * Returns the vector from the point perpendicular to the line (shortest distance).\r
351 * Where line is specified using two points or the coordinates of those points.\r
352 * @param p1 {Ext.draw.Point}\r
353 * @param p2 {Ext.draw.Point}\r
354 * @return {Ext.draw.Point}\r
355 */\r
356 getDistanceToLine: function (p1, p2) {\r
357 if (arguments.length === 4) {\r
358 p1 = new Ext.draw.Point(arguments[0], arguments[1]);\r
359 p2 = new Ext.draw.Point(arguments[2], arguments[3]);\r
360 }\r
361 // See http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation\r
362 var n = p2.sub(p1).normalize(),\r
363 pp1 = p1.sub(this);\r
364 return pp1.sub(n.mul(pp1.dot(n)));\r
365 },\r
366\r
367 /**\r
368 * Checks if both x and y coordinates of the point are zero.\r
369 * @return {Boolean}\r
370 */\r
371 isZero: function () {\r
372 return this.x === 0 && this.y === 0;\r
373 },\r
374\r
375 /**\r
376 * Checks if both x and y coordinates of the point are valid numbers.\r
377 * @return {Boolean}\r
378 */\r
379 isNumber: function () {\r
380 return Ext.isNumber(this.x + this.y);\r
381 }\r
382\r
383});