jsdk-offical
Version:
JSDK is the most comprehensive TypeScript framework, like JDK.
238 lines (206 loc) • 7.8 kB
text/typescript
/**
* @project JSDK
* @license MIT
* @website https://github.com/fengboyue/jsdk
*
* @version 2.5.0
* @author Frank.Feng
*/
/// <reference path="Constants.ts" />
module JS {
export namespace math {
/**
* 2D Point in Cartesian coordinate.
*/
export class Point2 {
x: number;
y: number;
constructor()
constructor(x: number, y: number)
constructor(x?: number, y?: number) {
this.x = x || 0;
this.y = y || 0
}
static ORIGIN = new Point2(0, 0);
static toPoint(p: ArrayPoint2): Point2 {
return new Point2().set(p)
}
static toArray(p: ArrayPoint2|Point2): ArrayPoint2 {
return p instanceof Point2?p.toArray():p
}
static polar2xy(d: number, rad: number): ArrayPoint2 {
let x: number, y: number;
switch (rad / Math.PI) {
case 0: x = d; y = 0; break;
case 0.5: x = 0; y = d; break;
case 1: x = -d; y = 0; break;
case 1.5: x = 0; y = -d; break;
case 2: x = d; y = 0; break;
default: x = d * Math.cos(rad); y = d * Math.sin(rad)
}
return [x.round(12), y.round(12)] //避免运算后的rad带来的精度误差
}
static xy2polar(x: number, y: number): PolarPoint2 {
return {
d: Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)),
a: Point2.radian(x, y)
}
}
static equal(p1: ArrayPoint2, p2: ArrayPoint2): boolean
static equal(x1: number, y1: number, x2: number, y2: number): boolean
static equal(x1: number | ArrayPoint2, y1: number | ArrayPoint2, x2?: number, y2?: number): boolean {
if (arguments.length > 3) return Floats.equal(<any>x1, x2) && Floats.equal(<any>y1, y2);
if(x1==void 0 && x1===y1) return true;
if(x1==void 0 || y1==void 0) return false;
let px1 = x1[0], py1 = x1[1], px2 = y1[0], py2 = y1[1];
return Floats.equal(px1, px2) && Floats.equal(py1, py2);
}
static isOrigin(x: number, y: number): boolean {
return this.equal(x, y, 0, 0)
}
/**
* Computes the square of the distance between p1 and p2.
*/
static distanceSq(x1: number, y1: number, x2: number, y2: number) {
let dx = x1 - x2,
dy = y1 - y2;
return dx * dx + dy * dy
}
/**
* Computes the distance between p1 and p2.
*/
static distance(x1: number, y1: number, x2: number, y2: number) {
return Math.sqrt(this.distanceSq(x1, y1, x2, y2))
}
/**
* The radian between the line(p1, origin) or the line(p1, p2) and X-axis. <br>
* 计算点到原点的连线与X轴的夹角的弧度。
*/
static radian(x1: number, y1: number, x2?:number, y2?:number): number {
let xx = x2||0, yy = y2||0;
if (this.isOrigin(x1, y1) && Point2.isOrigin(xx, yy)) return 0;
return Math.atan2(y1 - yy, x1 - xx)
}
set(p: ArrayPoint2 | Point2 | PolarPoint2) {
if (Types.isArray(p)) {
this.x = p[0];
this.y = p[1]
} else if ('x' in p) {
this.x = p.x;
this.y = p.y
} else {
let pp = Point2.polar2xy((<PolarPoint2>p).d, (<PolarPoint2>p).a);
this.x = pp[0];
this.y = pp[1]
}
return this
}
toPolar(): PolarPoint2 {
return Point2.xy2polar(this.x, this.y)
}
toArray(): ArrayPoint2 {
return [this.x, this.y]
}
clone() {
return new Point2(this.x, this.y)
}
/**
* Returns true if the L-infinite distance between this point and point p is less than or equal to the epsilon parameter, otherwise returns false.
* The L-infinite distance is equal to MAX[abs(x1-x2), abs(y1-y2), . . . ].
* @param p
*/
equals(p: Point2) {
return Floats.equal(this.x, p.x) && Floats.equal(this.y, p.y)
}
/**
* The radian between this point and X axis. <br>
* 计算点与X轴的夹角。
*/
radian(): number {
return Point2.radian(this.x, this.y)
}
/**
* Computes the square of the distance between this point and
* point p.
*/
distanceSq(x: number, y: number) {
return Point2.distanceSq(this.x, this.y, x, y)
}
/**
* Computes the distance between this point and point p.
*/
distance(x: number, y: number) {
return Math.sqrt(this.distanceSq(x, y))
}
/**
* Computes the L-1 (Manhattan) distance between this point and
* point p. The L-1 distance is equal to:
* abs(x1-x2) + abs(y1-y2).
*/
distanceL1(x: number, y: number) {
return Math.abs(this.x - x) + Math.abs(this.y - y)
}
/**
* Computes the L-infinite distance between this point and
* point p1. The L-infinite distance is equal to
* MAX[abs(x1-x2), abs(y1-y2)].
*/
distanceLinf(x: number, y: number) {
return Math.max(Math.abs(this.x - x), Math.abs(this.y - y))
}
translate(x: number, y: number) {
this.x += x;
this.y += y;
return this
}
moveTo(x: number, y: number) {
this.x = x;
this.y = y;
return this
}
/**
* Clamps this point to the range [min, max].
*/
clamp(min: number, max: number) {
let T = this;
if (T.x > max) {
T.x = max;
} else if (T.x < min) {
T.x = min;
}
if (T.y > max) {
T.y = max;
} else if (T.y < min) {
T.y = min;
}
return T
}
/**
* Clamps the minimum value of this point to the min parameter.
*/
clampMin(min: number) {
let T = this;
if (T.x < min) T.x = min;
if (T.y < min) T.y = min;
return T
}
/**
* Clamps the maximum value of this point to the max parameter.
*/
clampMax(max: number) {
let T = this;
if (T.x > max) T.x = max;
if (T.y > max) T.y = max;
return T
}
/**
* Move point toward along the radian.
*/
toward(step: number, rad: number) {
let p = Point2.polar2xy(step, rad);
return this.translate(p[0], p[1])
}
}
}
}
import Point2 = JS.math.Point2;