/* * === Geometory Three-Dimension === * * updated 2003/07/02 * * mail : peace@skipup.com * home : http://www.skipup.com/~peace/ */ /** * 3次元座標,3次元ベクトルを扱う. * インスタンス変数. * number x * number y * number z */ function class__Point3__(window) { var classId = Object.getClassName(arguments.callee); /** * void apply(Point3 p, Argument a) */ function apply(o, a) { switch (a.length) { case 0 : o.x = o.y = o.z = 0.0; return; case 1 : // Point3 || Array || Arguments || other var s = a[0]; if (typeof s == "object") { if (s.constructor === F) { // Point3 o.x = s.x; o.y = s.y; o.z = s.z; } else if (s.constructor === Array) { // Array o.x = s[0]; o.y = s[1]; o.z = s[2]; } else if (s.callee !== void 0) { // Argument apply(o, s); } else { // Other o.x = o.y = o.z = s; } return; } else { // Other o.x = o.y = o.z = s; return; } case 3 : // number, number, number || other, other, other o.x = a[0]; o.y = a[1]; o.z = a[2]; return; } } /** * コンストラクタ. * Point3() * Point3(number n) * Point3(Point3 p) * Point3(number[] ary) * Point3(arguments arg) * Point3(number x, number y, number z) */ var F = window[classId] = function() { if (this.constructor !== F) this.constructor = F; apply(this, arguments); }; var FP = F.prototype; /** * void add(Point3 p) * void add(Point3 p0, Point3 p1) */ FP.add = function(p0, p1) { if (arguments.length == 1) { this.x += p0.x; this.y += p0.y; this.z += p0.z; } else { this.x = p0.x + p1.x; this.y = p0.y + p1.y; this.z = p0.z + p1.z; } }; /** * void absolute() * void absolute(Point3 p) */ FP.absolute = function(p) { if (p === void 0) p = this; this.x = p.x >= 0.0 ? p.x : -p.x; this.y = p.y >= 0.0 ? p.y : -p.y; this.z = p.z >= 0.0 ? p.z : -p.z; }; /** * ベクトルとのなす角. * double angle(Point3 p) */ FP.angle = function(p) { var d = (this.x * p.x + this.y * p.y + this.z * p.z) / Math.sqrt((this.x * this.x + this.y * this.y + this.z * this.z) * (p.x * p.x + p.y * p.y + p.z * p.z)); if (d < -1.0) d = -1.0; else if (d > 1.0) d = 1.0; return Math.acos(d); }; /** * 外積. * void cross(Point3 p0, Point3 p1) */ FP.cross = function(p0, p1) { this.x = p0.y * p1.z - p1.y * p0.z; this.y = p0.z * p1.x - p1.z * p0.x; this.z = p0.x * p1.y - p1.x * p0.y; }; /** * double distance(Point3 p) */ FP.distance = function(p) { var x = this.x - p.x, y = this.y - p.y, z = this.z - p.z; return Math.sqrt(x * x + y * y + z * z); }; /** * double distance2(Point3 p) */ FP.distance2 = function(p) { var x = this.x - p.x, y = this.y - p.y, z = this.z - p.z; return x * x + y * y + z * z; }; /** * 内積. * double dot(Point3 p) */ FP.dot = function(p) { return this.x * p.x + this.y * p.y + this.z * p.z; }; /** * boolean equals(object p) */ FP.equals = function(p) { if (p == null || p.constructor !== F) return false; return this.x === p.x && this.y === p.y && this.z === p.z; }; /** * boolean epsilonEquals(Point3 p, double eps) */ FP.epsilonEquals = function(p, e) { var d = this.x - p.x; if ((d >= 0.0 ? d : -d) > e) return false; d = this.y - p.y; if ((d >= 0.0 ? d : -d) > e) return false; d = this.z - p.z; return (d >= 0.0 ? d : -d) <= e; }; /** * void integer() * void integer(Point3 p) */ FP.integer = function(p) { if (p === void 0) p = this; this.x = Math.floor(p.x); this.y = Math.floor(p.y); this.z = Math.floor(p.z); }; /** * boolean intEquals(Point3 p) */ FP.intEquals = function(p) { return Math.floor(this.x) == Math.floor(p.x) && Math.floor(this.y) == Math.floor(p.y) && Math.floor(this.z) == Math.floor(p.z); }; /** * 内分点. * void interpolate(Point3 p, double d) * void interpolate(Point3 p0, Point3 p1, double d) */ FP.interpolate = function(p0, p1, p2) { if (arguments.length == 2) { this.x = (1.0 - p1) * this.x + p1 * p0.x; this.y = (1.0 - p1) * this.y + p1 * p0.y; this.z = (1.0 - p1) * this.z + p1 * p0.z; } else { this.x = (1.0 - p2) * p0.x + p2 * p1.x; this.y = (1.0 - p2) * p0.y + p2 * p1.y; this.z = (1.0 - p2) * p0.z + p2 * p1.z; } }; /** * boolean isNaN() */ FP.isNaN = function() { return (isNaN(this.x) || isNaN(this.y) || isNaN(this.z)) || (this.x === "" || this.y === "" || this.z === ""); }; /** * double length() */ FP.length = function() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); }; /** * double length2() */ FP.length2 = function() { return this.x * this.x + this.y * this.y + this.z * this.z; }; /** * double max() */ FP.max = function() { return Math.max(this.x, this.y, this.z); }; /** * double min() */ FP.min = function() { return Math.min(this.x, this.y, this.z); }; /** * void negate() * void negate(Point3 p) */ FP.negate = function(p) { if (p === void 0) p = this; this.x = -p.x; this.y = -p.y; this.z = -p.z; }; /** * void normalize() * void normalize(Point3 p) */ FP.normalize = function(p) { if (arguments.length == 0) { var d = 1.0 / Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z); this.x *= d; this.y *= d; this.z *= d; } else { var d = 1.0 / Math.sqrt(p.x * p.x + p.y * p.y + p.z * p.z); this.x = p.x * d; this.y = p.y * d; this.z = p.z * d; } }; /** * void scale(double v) * void scale(double v, Point3 p) */ FP.scale = function(p0, p1) { if (arguments.length == 1) { this.x *= p0; this.y *= p0; this.z *= p0; } else { this.x = p1.x * p0; this.y = p1.y * p0; this.z = p1.z * p0; } }; /** * void scaleAdd(double v, Point3 p) * void scaleAdd(double v, Point3 p0, Point3 p1) */ FP.scaleAdd = function(p0, p1, p2) { if (arguments.length == 2) { this.x = this.x * p0 + p1.x; this.y = this.y * p0 + p1.y; this.z = this.z * p0 + p1.z; } else { this.x = p1.x * p0 + p2.x; this.y = p1.y * p0 + p2.y; this.z = p1.z * p0 + p2.z; } }; /** * void set(...) */ FP.set = function() { apply(this, arguments); }; /** * 極座標でメンバをセット. */ FP.setPolar = function(r, t, f) { this.x = r * Math.sin(t) * Math.cos(f); this.y = r * Math.sin(t) * Math.sin(f); this.z = r * Math.cos(t); }; /** * void sub(Point3 p) * void sub(Point3 p0, Point3 p1) */ FP.sub = function(p0, p1) { if (arguments.length == 1) { this.x -= p0.x; this.y -= p0.y; this.z -= p0.z; } else { this.x = p0.x - p1.x; this.y = p0.y - p1.y; this.z = p0.z - p1.z; } }; /** * number[] toArray() * number[] toArray(number[] ary) */ FP.toArray = function(a) { if (a === void 0) { return new Array(this.x, this.y, this.z); } else { a[0] = this.x; a[1] = this.y; a[2] = this.z; return a; } }; /** * string toString() */ FP.toString = function() { return "(" + this.x + "," + this.y + "," + this.z + ")"; }; } class__Point3__(window);