TouchDevelop/lib/Vector3.ts

113 строки
4.3 KiB
TypeScript

///<reference path='refs.ts'/>
module TDev.RT {
//? A 3D vector
//@ stem("p") immutable ctx(general,indexkey,walltap,json) serializable
export class Vector3
extends RTValue
{
constructor(public _x:number, public _y:number, public _z:number) {
super()
}
static mk(x : number, y : number, z : number) : Vector3
{
var v = new Vector3(x,y,z);
return v;
}
static zero = Vector3.mk(0, 0, 0);
public toJsonKey() {
return [this._x, this._y, this._z];
}
public keyCompareTo(o:any):number
{
var other:Vector3 = o;
var diff = this._x - other._x;
if (diff) return diff;
diff = this._y - other._y;
if (diff) return diff;
diff = this._z - other._z;
return diff;
}
public exportJson(ctx: JsonExportCtx): any {
return [this._x, this._y, this._z];
}
public importJson(ctx: JsonImportCtx, json: any): RT.RTValue {
Util.oops("should not call immutable instance for importing");
return undefined;
}
static mkFromJson(ctx: JsonImportCtx, json: any): RT.RTValue {
if (! Array.isArray(json) || json.length !== 3)
return undefined;
var ensurenr = (x) => (typeof x === "number" ? x : 0);
return new Vector3(ensurenr(json[0]), ensurenr(json[1]), ensurenr(json[2]));
}
//? Gets the x-component
public x() : number { return this._x; }
//? Gets the y-component
public y() : number { return this._y; }
//? Gets the z-component
public z() : number { return this._z; }
//? Gets the length of the vector
public length() : number { return Math.sqrt(this._x*this._x + this._y*this._y + this._z*this._z); }
//? Gets the distance between the two vectors
public distance(other:Vector3) : number { return this.subtract(other).length(); }
//? Returns a vector pointing in the opposite direction
public negate() : Vector3 { return Vector3.mk(-this._x,-this._y,-this._z); }
//? Returns a vector of one unit pointing in the same direction as the original vector
public normalize() : Vector3 { return this.scale(1 / this.length()); }
//? Adds a vector
public add(other:Vector3) : Vector3 { return Vector3.mk(this._x + other._x, this._y + other._y, this._z + other._z); }
//? Subtracts another vector
public subtract(other:Vector3) : Vector3 { return Vector3.mk(this._x - other._x, this._y - other._y, this._z - other._z); }
//? Multiplies component-wise with a vector
public multiply(other:Vector3) : Vector3 { return Vector3.mk(this._x*other._x, this._y * other._y, this._z * other._z); }
//? Multiplies with a scaling factor
public scale(scalar:number) : Vector3 { return Vector3.mk(this._x * scalar, this._y * scalar, this._z * scalar); }
//? Restricts the vector in the specified range
public clamp(min:Vector3, max:Vector3) : Vector3
{
return Vector3.mk(Math_.clamp(min._x, max._x, this._x), Math_.clamp(min._y, max._y, this._y), Math_.clamp(min._z, max._z, this._z));
}
//? Calculates the cross product with the other vector
public cross(other:Vector3) : Vector3
{
return Vector3.mk(this._y * other._z - this._z * other._y,
this._z * other._x - this._x * other._z,
this._x * other._y - this._y * other._x);
}
//? Linear interpolation between two vectors
public linear_interpolation(other:Vector3, amount:number) : Vector3
{
var a = Math_.normalize(amount);
var a1 = 1.0 - a;
return Vector3.mk(a * this._x + a1 * other._x, a * this._y + a1 * other._y, a * this._z + a1 * other._z);
}
//? Turns the vector into a string
public to_string() : string { return '(' + this._x.toPrecision(6) + ',' + this._y.toPrecision(6) + ',' + this._z.toPrecision(6) + ')'; }
public toString(): string { return this.to_string(); }
//? Displays the vector on the wall
public post_to_wall(s:IStackFrame) : void { super.post_to_wall(s) }
}
}