【发布时间】:2019-10-04 15:20:08
【问题描述】:
我正在尝试用 Javascript/Canvas 编写光线追踪器,来自“光线追踪器挑战”(Jamis Buck)。我编写的代码成功计算了 3x3 矩阵的行列式,但对于 4x4 矩阵却失败了,所以我删除了代码,取而代之的是我从 C 代码转换的以下代码。 (编译后的 C 版本可以工作。)它没有为 4x4 输入矩阵提供正确的行列式,即使它是从 C 移植来的,它确实可以工作。
我做错了什么?我错过了什么?
(我在底部包含了原始的、可工作的 C 代码。)
"use strict";
// HELPER FUNCTION
function initArray(rows, cols) {
var result = [];
for (var r = 0; r < rows; r++) {
result[r] = [];
for (var c = 0; c < cols; c++) {
result[r][c] = 0;
}
}
return result;
}
//--------------------------------
// DETERMINANT
// Function to get cofactor of mat[p][q] in temp[][]. n is current
// dimension of mat[][]
function getCofactor(mat, temp, p, q, n)
{
var i = 0, j = 0;
// Looping for each element of the matrix
for (var row = 0; row < n; row++)
{
for (var col = 0; col < n; col++)
{
// Copying into temporary matrix only those element
// which are not in given row and column
if (row != p && col != q)
{
temp[i][j++] = mat[row][col];
// Row is filled, so increase row index and
// reset col index
if (j == n - 1)
{
j = 0;
i++;
}
}
}
}
return temp;
}
/* Recursive function for finding determinant of matrix.
n is current dimension of mat[][]. */
function determinantOfMatrix(mat, n)
{
var D = 0; // Initialize result
// Base case : if matrix contains single element
if (n == 1)
return mat[0][0];
var temp = initArray(4, 4); // To store cofactors
var sign = 1; // To store sign multiplier
// Iterate for each element of first row
for (var f = 0; f < n; f++)
{
// Getting Cofactor of mat[0][f]
temp = getCofactor(mat, temp, 0, f, n);
D += sign * mat[0][f] * determinantOfMatrix(temp, n - 1);
// terms are to be added with alternate sign
sign = -sign;
}
return D;
}
// Finally, this is how I test it:
function test7() {
var m = initArray(4, 4);
m[0][0] = -2, m[0][1] = -8, m[0][2] = 3, m[0][3] = 5;
m[1][0] = -3, m[1][1] = 1, m[1][2] = 7, m[1][3] = 3;
m[2][0] = 1, m[2][1] = 2, m[2][2] = -9, m[2][3] = 6;
m[3][0] = 6, m[3][1] = 7, m[3][2] = 7, m[3][3] = -9;
/* 4x4 TEST MATRIX
-2, -8, 3, 5
-3, 1, 7, 3
1, 2, -9, 6
6, 7, 7, -9
*/
var determinant = determinantOfMatrix(m, 4 /*m.length*/);
alert("determinant = " + determinant); // SHOULD BE -4071
}
//---------------------- 下面是 C 代码,可以工作 --------
#include <stdio.h>
// Dimension of input square matrix
#define N 4
// Function to get cofactor of mat[p][q] in temp[][]. n is current
// dimension of mat[][]
void getCofactor(int mat[N][N], int temp[N][N], int p, int q, int n)
{
int i = 0, j = 0;
// Looping for each element of the matrix
for (int row = 0; row < n; row++)
{
for (int col = 0; col < n; col++)
{
// Copying into temporary matrix only those element
// which are not in given row and column
if (row != p && col != q)
{
temp[i][j++] = mat[row][col];
// Row is filled, so increase row index and
// reset col index
if (j == n - 1)
{
j = 0;
i++;
}
}
}
}
}
/* Recursive function for finding determinant of matrix.
n is current dimension of mat[][]. */
int determinantOfMatrix(int mat[N][N], int n)
{
int D = 0; // Initialize result
// Base case : if matrix contains single element
if (n == 1)
return mat[0][0];
int temp[N][N]; // To store cofactors
int sign = 1; // To store sign multiplier
// Iterate for each element of first row
for (int f = 0; f < n; f++)
{
// Getting Cofactor of mat[0][f]
getCofactor(mat, temp, 0, f, n);
D += sign * mat[0][f] * determinantOfMatrix(temp, n - 1);
// terms are to be added with alternate sign
sign = -sign;
}
return D;
}
// Driver program to test above functions
int main()
{
int mat[N][N] = {{-2, -8, 3, 5},
{-3, 1, 7, 3},
{1, 2, -9, 6},
{-6, 7, 7, -9}
};
printf("Determinant of the matrix is : %d", determinantOfMatrix(mat, N));
return 0;
}
【问题讨论】:
-
非常重要:始终在strict mode 中工作,这样您就不得不声明您的变量,并且不会以令人不快的重入意外而告终。
-
(这实际上可能是问题所在,特别是未声明的变量
f。) -
我试过“use strict”,还是不行。另外,请注意我刚刚稍微编辑了 test7() 函数,函数调用引用了“m2”而不是“m”,我已经更新了它。这显然不是问题......在添加“use strict”时,我还使用明确的“var”声明更新了各种 for 循环中的 var 创建......
-
m.rows?m没有rows属性。 -
C 和 Javascript 版本的输入不同:两个
m[3][0]符号不同。 (您可以使用m.length代替m.rows,并且您可能希望在getCofactor中使用var temp = initArray(n - 1, n - 1)。)
标签: javascript c matrix raytracing