Skip to content

Commit

Permalink
Merge pull request #246 from jsantell/remove-unused-distortion-methods
Browse files Browse the repository at this point in the history
Remove unused distortion methods
  • Loading branch information
toji authored May 31, 2017
2 parents 59cea6f + 2a8a4a7 commit 7ea0ad7
Showing 1 changed file with 0 additions and 133 deletions.
133 changes: 0 additions & 133 deletions src/distortion/distortion.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,137 +45,4 @@ Distortion.prototype.distort = function(radius) {
return (ret + 1) * radius;
};

// Functions below roughly ported from
// https://github.com/googlesamples/cardboard-unity/blob/master/Cardboard/Scripts/CardboardProfile.cs#L412

// Solves a small linear equation via destructive gaussian
// elimination and back substitution. This isn't generic numeric
// code, it's just a quick hack to work with the generally
// well-behaved symmetric matrices for least-squares fitting.
// Not intended for reuse.
//
// @param a Input positive definite symmetrical matrix. Destroyed
// during calculation.
// @param y Input right-hand-side values. Destroyed during calculation.
// @return Resulting x value vector.
//
Distortion.prototype.solveLinear_ = function(a, y) {
var n = a.length;

// Gaussian elimination (no row exchange) to triangular matrix.
// The input matrix is a A^T A product which should be a positive
// definite symmetrical matrix, and if I remember my linear
// algebra right this implies that the pivots will be nonzero and
// calculations sufficiently accurate without needing row
// exchange.
for (var j = 0; j < n - 1; ++j) {
for (var k = j + 1; k < n; ++k) {
var p = a[j][k] / a[j][j];
for (var i = j + 1; i < n; ++i) {
a[i][k] -= p * a[i][j];
}
y[k] -= p * y[j];
}
}
// From this point on, only the matrix elements a[j][i] with i>=j are
// valid. The elimination doesn't fill in eliminated 0 values.

var x = new Array(n);

// Back substitution.
for (var j = n - 1; j >= 0; --j) {
var v = y[j];
for (var i = j + 1; i < n; ++i) {
v -= a[i][j] * x[i];
}
x[j] = v / a[j][j];
}

return x;
};

// Solves a least-squares matrix equation. Given the equation A * x = y, calculate the
// least-square fit x = inverse(A * transpose(A)) * transpose(A) * y. The way this works
// is that, while A is typically not a square matrix (and hence not invertible), A * transpose(A)
// is always square. That is:
// A * x = y
// transpose(A) * (A * x) = transpose(A) * y <- multiply both sides by transpose(A)
// (transpose(A) * A) * x = transpose(A) * y <- associativity
// x = inverse(transpose(A) * A) * transpose(A) * y <- solve for x
// Matrix A's row count (first index) must match y's value count. A's column count (second index)
// determines the length of the result vector x.
Distortion.prototype.solveLeastSquares_ = function(matA, vecY) {
var i, j, k, sum;
var numSamples = matA.length;
var numCoefficients = matA[0].length;
if (numSamples != vecY.Length) {
throw new Error("Matrix / vector dimension mismatch");
}

// Calculate transpose(A) * A
var matATA = new Array(numCoefficients);
for (k = 0; k < numCoefficients; ++k) {
matATA[k] = new Array(numCoefficients);
for (j = 0; j < numCoefficients; ++j) {
sum = 0;
for (i = 0; i < numSamples; ++i) {
sum += matA[j][i] * matA[k][i];
}
matATA[k][j] = sum;
}
}

// Calculate transpose(A) * y
var vecATY = new Array(numCoefficients);
for (j = 0; j < numCoefficients; ++j) {
sum = 0;
for (i = 0; i < numSamples; ++i) {
sum += matA[j][i] * vecY[i];
}
vecATY[j] = sum;
}

// Now solve (A * transpose(A)) * x = transpose(A) * y.
return this.solveLinear_(matATA, vecATY);
};

/// Calculates an approximate inverse to the given radial distortion parameters.
Distortion.prototype.approximateInverse = function(maxRadius, numSamples) {
maxRadius = maxRadius || 1;
numSamples = numSamples || 100;
var numCoefficients = 6;
var i, j;

// R + K1*R^3 + K2*R^5 = r, with R = rp = distort(r)
// Repeating for numSamples:
// [ R0^3, R0^5 ] * [ K1 ] = [ r0 - R0 ]
// [ R1^3, R1^5 ] [ K2 ] [ r1 - R1 ]
// [ R2^3, R2^5 ] [ r2 - R2 ]
// [ etc... ] [ etc... ]
// That is:
// matA * [K1, K2] = y
// Solve:
// [K1, K2] = inverse(transpose(matA) * matA) * transpose(matA) * y
var matA = new Array(numCoefficients);
for (j = 0; j < numCoefficients; ++j) {
matA[j] = new Array(numSamples);
}
var vecY = new Array(numSamples);

for (i = 0; i < numSamples; ++i) {
var r = maxRadius * (i + 1) / numSamples;
var rp = this.distort(r);
var v = rp;
for (j = 0; j < numCoefficients; ++j) {
v *= rp * rp;
matA[j][i] = v;
}
vecY[i] = r - rp;
}

var inverseCoefficients = this.solveLeastSquares_(matA, vecY);

return new Distortion(inverseCoefficients);
};

module.exports = Distortion;

0 comments on commit 7ea0ad7

Please sign in to comment.