【问题标题】:Projected Shadow with shadow matrix, simple test fails带有阴影矩阵的投影阴影,简单测试失败
【发布时间】:2013-03-04 09:05:28
【问题描述】:

我编写了一个小程序来测试投影阴影的工作原理。

我想特别检查投影点(可能是三角形的顶点)不位于光源和平面之间而是位于光本身后面的情况,即光位于点之间还有飞机。

问题是我的小程序甚至无法在点位于光和平面之间的情况下工作。计算了几十遍,我猜应该是逻辑错误,但是找不到..

这里是代码

public class test {

    int x = 0;
    int y = 1;
    int z = 2;
    int w = 3;
    float floor[][] = {
        {-100.0f, -100.0f, 0.0f},
        {100.0f, -100.0f, 0.0f},
        {100.0f, 100.0f, 0.0f},
        {-100.0f, 100.0f, 0.0f}};
    private float shadow_floor[] = new float[16];
    float light_position[] = {0.0f, 0.0f, 10.0f, 1.0f};

    public test() {
        //Find floorplane based on thre known points
        float plane_floor[] = calculatePlane(floor[1], floor[2], floor[3]);

        //store shadowMatrix for floor
        shadow_floor = shadowMatrix(plane_floor, light_position);

        float[] point = new float[]{1.0f, 0.0f, 5.0f, 1.0f};

        float[] projectedPoint = pointFmatrixF(point, shadow_floor);

        System.out.println("point: (" + point[x] + ", " + point[y] + ", " + point[z] + ", "
                + point[w] + ")");
        System.out.println("projectedPoint: (" + projectedPoint[x] + ", " + projectedPoint[y]
                + ", " + projectedPoint[z] + ", " + projectedPoint[w] + ")");
    }

    public static void main(String args[]) {
        test test = new test();
    }

    // make shadow matrix
    public float[] shadowMatrix(float plane[], float light_pos[]) {
        float shadow_mat[] = new float[16];
        float dot;


        dot = plane[x] * light_pos[x] + plane[y] * light_pos[y]
                + plane[z] * light_pos[z] + plane[w] * light_pos[w];

        shadow_mat[0] = dot - light_pos[x] * plane[x];
        shadow_mat[4] = -light_pos[x] * plane[y];
        shadow_mat[8] = -light_pos[x] * plane[z];
        shadow_mat[12] = -light_pos[x] * plane[3];

        shadow_mat[1] = -light_pos[y] * plane[x];
        shadow_mat[5] = dot - light_pos[y] * plane[y];
        shadow_mat[9] = -light_pos[y] * plane[z];
        shadow_mat[13] = -light_pos[y] * plane[w];

        shadow_mat[2] = -light_pos[z] * plane[x];
        shadow_mat[6] = -light_pos[z] * plane[y];
        shadow_mat[10] = dot - light_pos[z] * plane[z];
        shadow_mat[14] = -light_pos[z] * plane[w];

        shadow_mat[3] = -light_pos[w] * plane[x];
        shadow_mat[7] = -light_pos[w] * plane[y];
        shadow_mat[11] = -light_pos[w] * plane[z];
        shadow_mat[15] = dot - light_pos[w] * plane[w];

        return shadow_mat;
    }

    public float[] calculatePlane(float p1[], float p2[], float p3[]) {
        //Array for planlikningen
        float plane[] = new float[4];

        //Gitt to vektorer (tre punkter) i planet kan normalen regnes ut
        //Vi vil ha aboluttverdier
        plane[x] = Math.abs(((p2[y] - p1[y]) * (p3[z] - p1[z])) - ((p2[z] - p1[z])
                * (p3[y] - p1[y])));
        plane[y] = Math.abs(((p2[z] - p1[z]) * (p3[x] - p1[x])) - ((p2[x] - p1[x])
                * (p3[z] - p1[z])));
        plane[z] = Math.abs(((p2[x] - p1[x]) * (p3[y] - p1[y])) - ((p2[y] - p1[y]) 
                * (p3[x] - p1[x])));
        plane[w] = -(plane[x] * p1[x] + plane[y] * p1[y] + plane[z] * p1[z]);


        return plane;
    }

    public float[] pointFmatrixF(float[] point, float[] matrix) {
        int x = 0;
        int y = 1;
        int z = 2;
        float[] transformedPoint = new float[4];

        transformedPoint[x] =
                matrix[0] * point[x]
                + matrix[4] * point[y]
                + matrix[8] * point[z]
                + matrix[12];
        transformedPoint[y] =
                matrix[1] * point[x]
                + matrix[5] * point[y]
                + matrix[9] * point[z]
                + matrix[13];
        transformedPoint[z] =
                matrix[2] * point[x]
                + matrix[6] * point[y]
                + matrix[10] * point[z]
                + matrix[14];
        transformedPoint[w] = 1;

        return transformedPoint;
    }
}

如果平面是xy平面,灯光在(0, 0, 10)上,点在(1, 0, 5)上,那么平面上的投影点应该是(2, 0, 0),但程序正在返回 (400000.0, 0.0, 0.0, 1.0)

【问题讨论】:

  • 我会在纸上完成这个示例,使用与您的程序相同的步骤,然后检查您的程序是否符合您必须执行的数学运算。 ...它甚至可以帮助将程序小心地复制到纸上。我发现手写比打印更容易擦除和更改。
  • 我试过了,但没用,我总是遇到同样的错误,错误是逻辑错误

标签: opengl matrix shadow


【解决方案1】:

已解决,我错误地假设投影点的最后一个坐标是 1,但事实并非如此。

https://math.stackexchange.com/questions/320527/projecting-a-point-on-a-plane-through-a-matrix

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多