Skip to content

Commit

Permalink
Clean up AffineMatrix / Transform a bit. Rename the AffineMatrix on T…
Browse files Browse the repository at this point in the history
…ransform to m, and export the AffineMatrix constructor.
  • Loading branch information
deanm committed Oct 13, 2009
1 parent c283526 commit eb71a3b
Showing 1 changed file with 78 additions and 81 deletions.
159 changes: 78 additions & 81 deletions pre3d.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,15 +213,6 @@ Pre3d = (function() {
this.e11 = e11;
};

// Transform the point |p| by the AffineMatrix |t|.
function transformPoint(t, p) {
return {
x: t.e0 * p.x + t.e1 * p.y + t.e2 * p.z + t.e3,
y: t.e4 * p.x + t.e5 * p.y + t.e6 * p.z + t.e7,
z: t.e8 * p.x + t.e9 * p.y + t.e10 * p.z + t.e11
};
}

// Matrix multiplication of AffineMatrix |a| x |b|. This is unrolled,
// and includes the calculations with the implied last row.
function multiplyAffine(a, b) {
Expand Down Expand Up @@ -333,117 +324,84 @@ Pre3d = (function() {
);
}

// Transform and return a new array of points with transform matrix |t|.
function transformPoints(t, ps) {
var il = ps.length;
var out = Array(il);
for (var i = 0; i < il; ++i) {
out[i] = transformPoint(t, ps[i]);
}
return out;
}

// Average a list of points, returning a new "centroid" point.
function averagePoints(ps) {
var avg = {x: 0, y: 0, z: 0};
for (var i = 0, il = ps.length; i < il; ++i) {
var p = ps[i];
avg.x += p.x;
avg.y += p.y;
avg.z += p.z;
}

// TODO(deanm): 1 divide and 3 multiplies cheaper than 3 divides?
var f = 1 / il;

avg.x *= f;
avg.y *= f;
avg.z *= f;

return avg;
}

// Push a and b away from each other. This means that the distance between
// a and be should be greater, by 2 units, 1 in each direction.
function pushPoints2dIP(a, b) {
var vec = unitVector2d(subPoints2d(b, a));
addPoints2dIP(b, b, vec);
subPoints2dIP(a, a, vec);
// Transform the point |p| by the AffineMatrix |t|.
function transformPoint(t, p) {
return {
x: t.e0 * p.x + t.e1 * p.y + t.e2 * p.z + t.e3,
y: t.e4 * p.x + t.e5 * p.y + t.e6 * p.z + t.e7,
z: t.e8 * p.x + t.e9 * p.y + t.e10 * p.z + t.e11
};
}

// A Transform is a convenient wrapper around a AffineMatrix, and it is what
// will be expose for more transforms (camera, etc).
// will be exposed for most transforms (camera, etc).
function Transform() {
this.reset();
}

// Returns a reference (not a copy) of the matrix object.
Transform.prototype.getMatrix = function() {
return this.matrix_;
}

// Reset the transform to the identity matrix.
Transform.prototype.reset = function() {
this.matrix_ = makeIdentityAffine();
this.m = makeIdentityAffine();
};

// TODO(deanm): We are creating two extra objects here. What would be most
// effecient is something like multiplyAffineByRotateXIP(this.matrix_), etc.
// effecient is something like multiplyAffineByRotateXIP(this.m), etc.
Transform.prototype.rotateX = function(theta) {
this.matrix_ =
multiplyAffine(makeRotateAffineX(theta), this.matrix_);
this.m =
multiplyAffine(makeRotateAffineX(theta), this.m);
};
Transform.prototype.rotateXPre = function(theta) {
this.matrix_ =
multiplyAffine(this.matrix_, makeRotateAffineX(theta));
this.m =
multiplyAffine(this.m, makeRotateAffineX(theta));
};

Transform.prototype.rotateY = function(theta) {
this.matrix_ =
multiplyAffine(makeRotateAffineY(theta), this.matrix_);
this.m =
multiplyAffine(makeRotateAffineY(theta), this.m);
};
Transform.prototype.rotateYPre = function(theta) {
this.matrix_ =
multiplyAffine(this.matrix_, makeRotateAffineY(theta));
this.m =
multiplyAffine(this.m, makeRotateAffineY(theta));
};

Transform.prototype.rotateZ = function(theta) {
this.matrix_ =
multiplyAffine(makeRotateAffineZ(theta), this.matrix_);
this.m =
multiplyAffine(makeRotateAffineZ(theta), this.m);
};
Transform.prototype.rotateZPre = function(theta) {
this.matrix_ =
multiplyAffine(this.matrix_, makeRotateAffineZ(theta));
this.m =
multiplyAffine(this.m, makeRotateAffineZ(theta));
};

Transform.prototype.translate = function(dx, dy, dz) {
this.matrix_ =
multiplyAffine(makeTranslateAffine(dx, dy, dz), this.matrix_);
this.m =
multiplyAffine(makeTranslateAffine(dx, dy, dz), this.m);
};
Transform.prototype.translatePre = function(dx, dy, dz) {
this.matrix_ =
multiplyAffine(this.matrix_, makeTranslateAffine(dx, dy, dz));
this.m =
multiplyAffine(this.m, makeTranslateAffine(dx, dy, dz));
};

Transform.prototype.scale = function(sx, sy, sz) {
this.matrix_ =
multiplyAffine(makeScaleAffine(sx, sy, sz), this.matrix_);
this.m =
multiplyAffine(makeScaleAffine(sx, sy, sz), this.m);
};

Transform.prototype.scalePre = function(sx, sy, sz) {
this.matrix_ =
multiplyAffine(this.matrix_, makeScaleAffine(sx, sy, sz));
this.m =
multiplyAffine(this.m, makeScaleAffine(sx, sy, sz));
};

Transform.prototype.transformPoint = function(p) {
return transformPoint(this.matrix_, p);
return transformPoint(this.m, p);
};

Transform.prototype.multTransform = function(t) {
this.matrix_ = multiplyAffine(this.matrix_, t.matrix_);
this.m = multiplyAffine(this.m, t.m);
};

Transform.prototype.setDCM = function(u, v, w) {
var m = this.matrix_;
var m = this.m;
m.e0 = u.x; m.e4 = u.y; m.e8 = u.z;
m.e1 = v.x; m.e5 = v.y; m.e9 = v.z;
m.e2 = w.x; m.e6 = w.y; m.e10 = w.z;
Expand All @@ -452,10 +410,48 @@ Pre3d = (function() {
Transform.prototype.dup = function() {
// TODO(deanm): This should be better.
var tm = new Transform();
tm.matrix_ = dupAffine(this.matrix_);
tm.m = dupAffine(this.m);
return tm;
};

// Transform and return a new array of points with transform matrix |t|.
function transformPoints(t, ps) {
var il = ps.length;
var out = Array(il);
for (var i = 0; i < il; ++i) {
out[i] = transformPoint(t, ps[i]);
}
return out;
}

// Average a list of points, returning a new "centroid" point.
function averagePoints(ps) {
var avg = {x: 0, y: 0, z: 0};
for (var i = 0, il = ps.length; i < il; ++i) {
var p = ps[i];
avg.x += p.x;
avg.y += p.y;
avg.z += p.z;
}

// TODO(deanm): 1 divide and 3 multiplies cheaper than 3 divides?
var f = 1 / il;

avg.x *= f;
avg.y *= f;
avg.z *= f;

return avg;
}

// Push a and b away from each other. This means that the distance between
// a and be should be greater, by 2 units, 1 in each direction.
function pushPoints2dIP(a, b) {
var vec = unitVector2d(subPoints2d(b, a));
addPoints2dIP(b, b, vec);
subPoints2dIP(a, a, vec);
}

// RGBA is our simple representation for colors.
function RGBA(r, g, b, a) {
this.setRGBA(r, g, b, a);
Expand Down Expand Up @@ -806,8 +802,8 @@ Pre3d = (function() {
var quad_callback = this.quad_callback;

// Our vertex transformation matrix.
var t = multiplyAffine(this.camera.transform.getMatrix(),
this.transform.getMatrix());
var t = multiplyAffine(this.camera.transform.m,
this.transform.m);
// Our normal transformation matrix.
var tn = transAdjoint(t);

Expand Down Expand Up @@ -1027,8 +1023,8 @@ Pre3d = (function() {
var ctx = this.ctx;
var opts = opts || { };

var t = multiplyAffine(this.camera.transform.getMatrix(),
this.transform.getMatrix());
var t = multiplyAffine(this.camera.transform.m,
this.transform.m);

var screen_points = this.projectPointsToCanvas(
transformPoints(t, path.points));
Expand Down Expand Up @@ -1067,6 +1063,7 @@ Pre3d = (function() {

return {
RGBA: RGBA,
AffineMatrix: AffineMatrix,
Transform: Transform,
QuadFace: QuadFace,
Shape: Shape,
Expand Down

0 comments on commit eb71a3b

Please sign in to comment.