GameLib.API.Quaternion.Points = function () { this.vectors = []; }; GameLib.API.Quaternion.Points.prototype.add = function (vector) { if (vector instanceof GameLib.API.Vector3) { vector = new GameLib.API.Quaternion( vector.x, vector.y, vector.z, 1 ) } if (!vector instanceof GameLib.API.Quaternion) { console.warn("Vector needs to be of type Quaternion"); throw new Error("Vector needs to be of type Quaternion"); } this.vectors.push(vector); return this; }; GameLib.API.Quaternion.Points.prototype.copy = function () { var vectors = []; for (var i = 0; i < this.vectors.length; i++) { vectors.push(this.vectors[i].copy()); } return vectors; }; GameLib.API.Quaternion.Points.prototype.maximizeXDistance = function (grain) { // console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); var multiplier = 0; var rotationMatrixY = new GameLib.API.Matrix4().rotationMatrixY(grain); var totalRadians = 0; var backupVectors = this.copy(); var maxXDistance = 0; for (var i = 0; i < Math.PI * 2; i += grain) { multiplier++; for (var j = 0; j < this.vectors.length; j++) { this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]); } var distances = this.distances(); if (distances.x > maxXDistance) { maxXDistance = distances.x; totalRadians = multiplier * grain; } } this.vectors = backupVectors; // console.log("distance: " + maxXDistance + " radians : " + totalRadians); var maxRotationMatrix = new GameLib.API.Matrix4().rotationMatrixY(totalRadians); for (var k = 0; k < this.vectors.length; k++) { this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); } // console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); }; GameLib.API.Quaternion.Points.prototype.maximizeYDistance = function (grain) { // console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); var multiplier = 0; var rotationMatrixX = new GameLib.API.Matrix4().rotationMatrixX(grain); var totalRadians = 0; var backupVectors = this.copy(); var maxYDistance = 0; for (var i = 0; i < Math.PI * 2; i += grain) { multiplier++; for (var j = 0; j < this.vectors.length; j++) { this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]); } var distances = this.distances(); if (distances.y > maxYDistance) { maxYDistance = distances.y; totalRadians = multiplier * grain; } } this.vectors = backupVectors; // console.log("distance: " + maxYDistance + " radians : " + totalRadians); var maxRotationMatrix = new GameLib.API.Matrix4().rotationMatrixX(totalRadians); for (var k = 0; k < this.vectors.length; k++) { this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); } // console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); }; GameLib.API.Quaternion.Points.prototype.lookAt = function (at, up) { var polyCenter = this.average(); console.log("poly center : " + JSON.stringify(polyCenter)); var lookAtMatrix = new GameLib.API.Matrix4().lookAt(polyCenter, at, up); lookAtMatrix.rows[0] = new GameLib.API.Quaternion(1, 0, 0, 0); lookAtMatrix.rows[1] = new GameLib.API.Quaternion(0, 0, 1, 0); lookAtMatrix.rows[2] = new GameLib.API.Quaternion(0, 1, 0, 0); console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2)); for (var i = 0; i < this.vectors.length; i++) { console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i])); this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]); console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i])); } }; GameLib.API.Quaternion.Points.prototype.distances = function () { var minX = this.vectors[0].x; var minY = this.vectors[0].y; var minZ = this.vectors[0].z; var maxX = this.vectors[0].x; var maxY = this.vectors[0].y; var maxZ = this.vectors[0].z; for (var i = 0; i < this.vectors.length; i++) { if (this.vectors[i].x < minX) { minX = this.vectors[i].x; } if (this.vectors[i].y < minY) { minY = this.vectors[i].y; } if (this.vectors[i].z < minZ) { minZ = this.vectors[i].z; } if (this.vectors[i].x > maxX) { maxX = this.vectors[i].x; } if (this.vectors[i].y > maxY) { maxY = this.vectors[i].y; } if (this.vectors[i].z > maxZ) { maxZ = this.vectors[i].z; } } return new GameLib.API.Vector3( Math.abs(maxX - minX), Math.abs(maxY - minY), Math.abs(maxY - minZ) ) }; GameLib.API.Quaternion.Points.prototype.average = function () { var averageX = 0; var averageY = 0; var averageZ = 0; for (var i = 0; i < this.vectors.length; i++) { averageX += this.vectors[i].x; averageY += this.vectors[i].y; averageZ += this.vectors[i].z; } return new GameLib.API.Vector3( averageX / this.vectors.length, averageY / this.vectors.length, averageZ / this.vectors.length ); }; GameLib.API.Quaternion.Points.prototype.negate = function () { for (var i = 0; i < this.vectors.length; i++) { this.vectors[i].x *= -1; this.vectors[i].y *= -1; this.vectors[i].z *= -1; } return this; }; GameLib.API.Quaternion.Points.prototype.toOrigin = function () { var distanceFromOrigin = this.average().negate(); for (var i = 0; i < this.vectors.length; i++) { this.vectors[i].translate(distanceFromOrigin); } };