Path: blob/trunk/third_party/closure/goog/math/coordinate.js
4527 views
/**1* @license2* Copyright The Closure Library Authors.3* SPDX-License-Identifier: Apache-2.04*/56/**7* @fileoverview A utility class for representing two-dimensional positions.8*/91011goog.provide('goog.math.Coordinate');1213goog.require('goog.math');14151617/**18* Class for representing coordinates and positions.19* @param {number=} opt_x Left, defaults to 0.20* @param {number=} opt_y Top, defaults to 0.21* @struct22* @constructor23*/24goog.math.Coordinate = function(opt_x, opt_y) {25'use strict';26/**27* X-value28* @type {number}29*/30this.x = (opt_x !== undefined) ? opt_x : 0;3132/**33* Y-value34* @type {number}35*/36this.y = (opt_y !== undefined) ? opt_y : 0;37};383940/**41* Returns a new copy of the coordinate.42* @return {!goog.math.Coordinate} A clone of this coordinate.43*/44goog.math.Coordinate.prototype.clone = function() {45'use strict';46return new goog.math.Coordinate(this.x, this.y);47};484950if (goog.DEBUG) {51/**52* Returns a nice string representing the coordinate.53* @return {string} In the form (50, 73).54* @override55*/56goog.math.Coordinate.prototype.toString = function() {57'use strict';58return '(' + this.x + ', ' + this.y + ')';59};60}616263/**64* Returns whether the specified value is equal to this coordinate.65* @param {*} other Some other value.66* @return {boolean} Whether the specified value is equal to this coordinate.67*/68goog.math.Coordinate.prototype.equals = function(other) {69'use strict';70return other instanceof goog.math.Coordinate &&71goog.math.Coordinate.equals(this, other);72};737475/**76* Compares coordinates for equality.77* @param {goog.math.Coordinate} a A Coordinate.78* @param {goog.math.Coordinate} b A Coordinate.79* @return {boolean} True iff the coordinates are equal, or if both are null.80*/81goog.math.Coordinate.equals = function(a, b) {82'use strict';83if (a == b) {84return true;85}86if (!a || !b) {87return false;88}89return a.x == b.x && a.y == b.y;90};919293/**94* Returns the distance between two coordinates.95* @param {!goog.math.Coordinate} a A Coordinate.96* @param {!goog.math.Coordinate} b A Coordinate.97* @return {number} The distance between `a` and `b`.98*/99goog.math.Coordinate.distance = function(a, b) {100'use strict';101var dx = a.x - b.x;102var dy = a.y - b.y;103return Math.sqrt(dx * dx + dy * dy);104};105106107/**108* Returns the magnitude of a coordinate.109* @param {!goog.math.Coordinate} a A Coordinate.110* @return {number} The distance between the origin and `a`.111*/112goog.math.Coordinate.magnitude = function(a) {113'use strict';114return Math.sqrt(a.x * a.x + a.y * a.y);115};116117118/**119* Returns the angle from the origin to a coordinate.120* @param {!goog.math.Coordinate} a A Coordinate.121* @return {number} The angle, in degrees, clockwise from the positive X122* axis to `a`.123*/124goog.math.Coordinate.azimuth = function(a) {125'use strict';126return goog.math.angle(0, 0, a.x, a.y);127};128129130/**131* Returns the squared distance between two coordinates. Squared distances can132* be used for comparisons when the actual value is not required.133*134* Performance note: eliminating the square root is an optimization often used135* in lower-level languages, but the speed difference is not nearly as136* pronounced in JavaScript (only a few percent.)137*138* @param {!goog.math.Coordinate} a A Coordinate.139* @param {!goog.math.Coordinate} b A Coordinate.140* @return {number} The squared distance between `a` and `b`.141*/142goog.math.Coordinate.squaredDistance = function(a, b) {143'use strict';144var dx = a.x - b.x;145var dy = a.y - b.y;146return dx * dx + dy * dy;147};148149150/**151* Returns the difference between two coordinates as a new152* goog.math.Coordinate.153* @param {!goog.math.Coordinate} a A Coordinate.154* @param {!goog.math.Coordinate} b A Coordinate.155* @return {!goog.math.Coordinate} A Coordinate representing the difference156* between `a` and `b`.157*/158goog.math.Coordinate.difference = function(a, b) {159'use strict';160return new goog.math.Coordinate(a.x - b.x, a.y - b.y);161};162163164/**165* Returns the sum of two coordinates as a new goog.math.Coordinate.166* @param {!goog.math.Coordinate} a A Coordinate.167* @param {!goog.math.Coordinate} b A Coordinate.168* @return {!goog.math.Coordinate} A Coordinate representing the sum of the two169* coordinates.170*/171goog.math.Coordinate.sum = function(a, b) {172'use strict';173return new goog.math.Coordinate(a.x + b.x, a.y + b.y);174};175176177/**178* Rounds the x and y fields to the next larger integer values.179* @return {!goog.math.Coordinate} This coordinate with ceil'd fields.180*/181goog.math.Coordinate.prototype.ceil = function() {182'use strict';183this.x = Math.ceil(this.x);184this.y = Math.ceil(this.y);185return this;186};187188189/**190* Rounds the x and y fields to the next smaller integer values.191* @return {!goog.math.Coordinate} This coordinate with floored fields.192*/193goog.math.Coordinate.prototype.floor = function() {194'use strict';195this.x = Math.floor(this.x);196this.y = Math.floor(this.y);197return this;198};199200201/**202* Rounds the x and y fields to the nearest integer values.203* @return {!goog.math.Coordinate} This coordinate with rounded fields.204*/205goog.math.Coordinate.prototype.round = function() {206'use strict';207this.x = Math.round(this.x);208this.y = Math.round(this.y);209return this;210};211212213/**214* Translates this box by the given offsets. If a `goog.math.Coordinate`215* is given, then the x and y values are translated by the coordinate's x and y.216* Otherwise, x and y are translated by `tx` and `opt_ty`217* respectively.218* @param {number|goog.math.Coordinate} tx The value to translate x by or the219* the coordinate to translate this coordinate by.220* @param {number=} opt_ty The value to translate y by.221* @return {!goog.math.Coordinate} This coordinate after translating.222*/223goog.math.Coordinate.prototype.translate = function(tx, opt_ty) {224'use strict';225if (tx instanceof goog.math.Coordinate) {226this.x += tx.x;227this.y += tx.y;228} else {229this.x += Number(tx);230if (typeof opt_ty === 'number') {231this.y += opt_ty;232}233}234return this;235};236237238/**239* Scales this coordinate by the given scale factors. The x and y values are240* scaled by `sx` and `opt_sy` respectively. If `opt_sy`241* is not given, then `sx` is used for both x and y.242* @param {number} sx The scale factor to use for the x dimension.243* @param {number=} opt_sy The scale factor to use for the y dimension.244* @return {!goog.math.Coordinate} This coordinate after scaling.245*/246goog.math.Coordinate.prototype.scale = function(sx, opt_sy) {247'use strict';248var sy = (typeof opt_sy === 'number') ? opt_sy : sx;249this.x *= sx;250this.y *= sy;251return this;252};253254255/**256* Rotates this coordinate clockwise about the origin (or, optionally, the given257* center) by the given angle, in radians.258* @param {number} radians The angle by which to rotate this coordinate259* clockwise about the given center, in radians.260* @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults261* to (0, 0) if not given.262*/263goog.math.Coordinate.prototype.rotateRadians = function(radians, opt_center) {264'use strict';265var center = opt_center || new goog.math.Coordinate(0, 0);266267var x = this.x;268var y = this.y;269var cos = Math.cos(radians);270var sin = Math.sin(radians);271272this.x = (x - center.x) * cos - (y - center.y) * sin + center.x;273this.y = (x - center.x) * sin + (y - center.y) * cos + center.y;274};275276277/**278* Rotates this coordinate clockwise about the origin (or, optionally, the given279* center) by the given angle, in degrees.280* @param {number} degrees The angle by which to rotate this coordinate281* clockwise about the given center, in degrees.282* @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults283* to (0, 0) if not given.284*/285goog.math.Coordinate.prototype.rotateDegrees = function(degrees, opt_center) {286'use strict';287this.rotateRadians(goog.math.toRadians(degrees), opt_center);288};289290291