flexible-vector
Version:
Javascript vector library with flexible accessors
404 lines • 13.9 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
var createIterator = function (v) {
return function () {
var i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
i = 0;
_a.label = 1;
case 1:
if (!(i < v.size)) return [3 /*break*/, 4];
return [4 /*yield*/, v.get(i)];
case 2:
_a.sent();
_a.label = 3;
case 3:
i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/];
}
});
};
};
var BaseVector = /** @class */ (function () {
function BaseVector() {
var _components = [];
for (var _i = 0; _i < arguments.length; _i++) {
_components[_i] = arguments[_i];
}
// implementing the iterator protocol
this[Symbol.iterator] = createIterator(this);
this.components = _components;
}
BaseVector.prototype.inspect = function () {
return "Vector(" + this.components.join(",") + ")";
};
/**
* returns the components in an array. Note you can also use the iterator pattern
*/
BaseVector.prototype.toArray = function () {
return this.components;
};
/**
* get a component from the vector
*/
BaseVector.prototype.get = function (index) {
return this.components[index];
};
/**
* set a component of the vector
*/
BaseVector.prototype.set = function (index, value) {
this.components[index] = value;
};
Object.defineProperty(BaseVector.prototype, "size", {
/**
* the dimensionality of the vector
*/
get: function () {
return this.components.length;
},
enumerable: true,
configurable: true
});
/**
* check whether a vector equals another
*/
BaseVector.prototype.equals = function (other) {
var o = other.toArray();
return this.components.every(function (c, i) { return c === o[i]; });
};
/**
* squared norm of the vector
*/
BaseVector.prototype.n2 = function () {
return this.components.reduce(function (sum, c) { return sum + c * c; }, 0);
};
/**
* norm of the vector
*/
BaseVector.prototype.norm = function () {
return Math.sqrt(this.n2());
};
/**
* inner product with another vector
*/
BaseVector.prototype.dot = function (other) {
if (other.size !== this.size) {
throw new Error("can only dot product vectors of same size, got " + this.size + " and " + other.size);
}
var o = other.toArray();
return this.components.reduce(function (sum, c, i) { return sum + c * o[i]; }, 0);
};
/**
* adds another vector to this one
*/
BaseVector.prototype.plus = function (other) {
if (other.size !== this.size) {
throw new Error("can only add product vectors of same size, got " + this.size + " and " + other.size);
}
var o = other.toArray();
return exports.vector.apply(void 0, __spread(this.components.map(function (c, i) { return c + o[i]; })));
};
/**
* multiplies by a scalar
*/
BaseVector.prototype.times = function (scalar) {
return exports.vector.apply(void 0, __spread(this.components.map(function (c) { return c * scalar; })));
};
/**
* subtracts another vector from this one
*/
BaseVector.prototype.minus = function (other) {
return this.plus(other.times(-1));
};
/**
* normalizes the vector to length 1 or 0 if it was already 0
*/
BaseVector.prototype.normalize = function () {
var n = this.norm();
if (n === 0)
return this;
return this.times(1 / n);
};
return BaseVector;
}());
var BaseVector2 = /** @class */ (function (_super) {
__extends(BaseVector2, _super);
function BaseVector2() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(BaseVector2.prototype, "x", {
/**
* the x (0) component
*/
get: function () {
return this.components[0];
},
set: function (value) {
this.components[0] = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(BaseVector2.prototype, "y", {
/**
* the y (1) component
*/
get: function () {
return this.components[1];
},
set: function (value) {
this.components[1] = value;
},
enumerable: true,
configurable: true
});
return BaseVector2;
}(BaseVector));
var RealVector2 = /** @class */ (function (_super) {
__extends(RealVector2, _super);
function RealVector2() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* rotate the vector
*/
RealVector2.prototype.rotate = function (angle) {
var ca = Math.cos(angle);
var sa = Math.sin(angle);
return exports.vector2(this.x * ca - this.y * sa, this.x * sa + this.y * ca);
};
RealVector2.prototype.cross = function (other) {
return this.x * other.y - this.y * other.x;
};
RealVector2.prototype.angle = function () {
return Math.atan2(this.y, this.x);
};
return RealVector2;
}(BaseVector2));
var BaseVector3 = /** @class */ (function (_super) {
__extends(BaseVector3, _super);
function BaseVector3() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(BaseVector3.prototype, "z", {
/**
* the z (2) component
*/
get: function () {
return this.components[2];
},
set: function (value) {
this.components[2] = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(BaseVector3.prototype, "r", {
/**
* the red (0) component
*/
get: function () {
return this.components[0];
},
set: function (value) {
this.components[0] = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(BaseVector3.prototype, "g", {
/**
* the green (1) component
*/
get: function () {
return this.components[1];
},
set: function (value) {
this.components[1] = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(BaseVector3.prototype, "b", {
/**
* the blue (2) component
*/
get: function () {
return this.components[2];
},
set: function (value) {
this.components[2] = value;
},
enumerable: true,
configurable: true
});
return BaseVector3;
}(BaseVector2));
var BaseVector4 = /** @class */ (function (_super) {
__extends(BaseVector4, _super);
function BaseVector4() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(BaseVector4.prototype, "a", {
/**
* the alpha (3) component
*/
get: function () {
return this.components[3];
},
set: function (value) {
this.components[3] = value;
},
enumerable: true,
configurable: true
});
return BaseVector4;
}(BaseVector3));
var extendVector = function (v) {
return new Proxy(v, {
get: function (obj, prop) {
if (obj[prop] !== undefined) {
return obj[prop];
}
else if (typeof prop === "string") {
if (prop.length > 1 && prop.match(/[xyz]{2,3}|[rgba]{2,4}/)) {
var names = prop.split("");
var values = names.map(function (name) { return obj[name]; });
return exports.vector.apply(void 0, __spread(values));
}
else if (prop.match(/\d+/)) {
return obj.get(parseInt(prop, 10));
}
}
},
set: function (obj, prop, value, receiver) {
if (typeof prop === "string") {
if (prop.length > 1 && prop.match(/[xyz]{2,3}|[rgba]{2,4}/)) {
var names = prop.split("");
names.forEach(function (name, index) {
obj[name] = value[index];
});
return true;
}
else if (prop.match(/\d+/)) {
obj.set(parseInt(prop, 10), value);
return true;
}
}
return Reflect.set(obj, prop, value, receiver);
},
});
};
exports.vector = function () {
var components = [];
for (var _i = 0; _i < arguments.length; _i++) {
components[_i] = arguments[_i];
}
switch (components.length) {
case 2:
return exports.vector2.apply(void 0, __spread(components));
case 3:
return exports.vector3.apply(void 0, __spread(components));
case 4:
return exports.vector4.apply(void 0, __spread(components));
default:
return extendVector(new (BaseVector.bind.apply(BaseVector, __spread([void 0], components)))());
}
};
exports.vector2 = function () {
var components = [];
for (var _i = 0; _i < arguments.length; _i++) {
components[_i] = arguments[_i];
}
if (components.length !== 2) {
throw new Error("vector2 expected 2 components");
}
var v2 = new (RealVector2.bind.apply(RealVector2, __spread([void 0], components)))();
return extendVector(v2);
};
exports.vector3 = function () {
var components = [];
for (var _i = 0; _i < arguments.length; _i++) {
components[_i] = arguments[_i];
}
if (components.length !== 3) {
throw new Error("vector3 expected 3 components");
}
return extendVector(new (BaseVector3.bind.apply(BaseVector3, __spread([void 0], components)))());
};
exports.vector4 = function () {
var components = [];
for (var _i = 0; _i < arguments.length; _i++) {
components[_i] = arguments[_i];
}
if (components.length !== 4) {
throw new Error("vector4 expected 4 components");
}
return extendVector(new (BaseVector4.bind.apply(BaseVector4, __spread([void 0], components)))());
};
exports.default = exports.vector;
//# sourceMappingURL=index.js.map