矩阵变换,绕x轴旋转

Veg*_*gar 1 c# matrix

我在“ Ray Tracer挑战”中苦苦挣扎,在第4章中遇到了一个我无法超越的测试案例。

Scenario: Rotating a point around the x axis
  Given p ? point(0, 1, 0)
    And half_quarter ? rotation_x(? / 4)
    And full_quarter ? rotation_x(? / 2)
  Then half_quarter * p = point(0, ?2/2, ?2/2)
    And full_quarter * p = point(0, 0, 1)
Run Code Online (Sandbox Code Playgroud)

第一个断言(half_quarter)可以正常工作,但是第二个断言(full_quarter)失败。

期望Matrix.Multiply(full_quarter,p)等于(0,0,1,1),但找到(0,6.12323399573677E-17,1,1)。'

我的实现rotation_x如下:

        public static double[,] rotation_x(double radians)
        {
            var cos = Math.Cos(radians);
            var sin = Math.Sin(radians);

            return new[,]
            {
                { 1,   0,    0, 0 },
                { 0, cos, -sin, 0 },
                { 0, sin,  cos, 0 },
                { 0,   0,    0, 1 }
            });
        }
Run Code Online (Sandbox Code Playgroud)

这是我的乘法方法:

        public static double[] Multiply(double[,] a, (double x, double y, double z, double w) b)
        {
            var product = new double[4];

            for (var r = 0; r < 4; r++)
            {
                product[r] = a[r, 0] * b.x
                           + a[r, 1] * b.y
                           + a[r, 2] * b.z
                           + a[r, 3] * b.w
                           ;
            }

            return product;
        }
Run Code Online (Sandbox Code Playgroud)

在前面的章节中,我有很多关于矩阵和向量乘法的测试案例,因此,我很确定该部分可以正常工作。但是还有什么可能是错的?

Eri*_*ert 6

您正在传递?的某个值,但Math.PI不完全等于?。大约等于?到约17个有效数字之内。

正弦的正弦?正好为零。非常接近的正弦值?非常接近零。您得到的是:6 x 10 -17几乎接近零。

同样,π/ 2的余弦正好为零,但是您传入的π/ 2的值仅精确到17位,因此结果仅精确到17位。

类似地,Sqrt(2.0)/2.0不是精确地为2/2。近似值精确到约17个小数位。

系统中每个不是整数的数字都只能在17个小数位内正确,因此这里没有奥秘。您的结果正确到小数点后17位,因为您的输入正确到小数点后17位。您只能得到与输入一样多的精度。双精度不是无限精度!

(顺便说一下,很好地使用元组类型-但考虑使结构代表这些概念中的某些;这样,您可以将与这些概念相关联的方法放入结构中。)

  • @Vegar:为了澄清您对在家中以下人士的评论:您没有六分的东西。您有0.00000000000000006的东西。** E-17表示乘以10到负数17 **。 (4认同)