- var tmp = this.dot(point, axis) * (1 - cosangle);
- return [axis[0]*tmp + point[0]*cosangle + (-axis[2]*point[1] + axis[1]*point[2])*sinangle,
- axis[1]*tmp + point[1]*cosangle + ( axis[2]*point[0] - axis[0]*point[2])*sinangle,
- axis[2]*tmp + point[2]*cosangle + (-axis[1]*point[0] + axis[0]*point[1])*sinangle];
+ var rotated = [];
+ for (var i = 0; i < points.length; i++) {
+ var p = points[i];
+ var tmp = this.dot(p, axis) * (1 - cosangle);
+ rotated[i] = [
+ axis[0]*tmp + p[0]*cosangle + (-axis[2]*p[1] + axis[1]*p[2])*sinangle,
+ axis[1]*tmp + p[1]*cosangle + ( axis[2]*p[0] - axis[0]*p[2])*sinangle,
+ axis[2]*tmp + p[2]*cosangle + (-axis[1]*p[0] + axis[0]*p[1])*sinangle];
+ }
+ return rotated;
+ },
+ rotate_onto: function(points, a, b) {
+ // Rotate points such that a (in points-space) maps onto b
+ // by crossing a and b to get a rotation axis and using
+ // angle_between to get a rotation angle.
+ var angle = this.angle_between(this.unit(a), this.unit(b));
+ if (Math.abs(angle) < 1e-15) {
+ // No siginificant rotation to perform. Bail to avoid
+ // NaNs and numerical error
+ return points;
+ }
+ var axis = this.unit(this.cross(a, b));
+ return this.rotate_about_origin(points, axis, angle);
+ },
+ rotate: function(points, center, axis, angle) { // axis must be a unit vector
+ return this.translate(
+ this.rotate_about_origin(
+ this.translate(points, this.neg(center)),
+ axis,
+ angle),
+ center);