为什么我的旋转矩阵无法正常工作?

发布于 2025-02-12 08:10:48 字数 1905 浏览 5 评论 0 原文

我一直在这个简单的栅格中工作,但是我导入的立方体无法正确旋转。这是一个问题的图片: ”在此处输入图像描述”

我从此 wikipedia page 。这是旋转功能:

    pub fn rotate(self, theta: f32, axis: Vec3) -> Obj {

        let u = Vec3::normalize(axis);
        
        let mut tempVec: Vec<Vec3> = vec![];

        let thetaCos = theta.cos();
        let thetaSin = theta.sin();

        for i in 0..self.vertices.len() {
        tempVec.push(Vec3::new( (thetaCos + u.x.powf(2.) * (1. - thetaCos))    * self.vertices[i].x + (u.x * u.y * (1. - thetaCos) - u.z * thetaSin) * self.vertices[i].y + (u.x * u.z * (1. - thetaCos) + u.y * thetaSin) * self.vertices[i].z,
                                (u.y * u.x * (1. - thetaCos) + u.z * thetaSin) * self.vertices[i].x + (thetaCos + u.y.powf(2.) * (1. - thetaCos))    * self.vertices[i].y + (u.y * u.z * (1. - thetaCos) - u.x * thetaSin) * self.vertices[i].z,
                                (u.z * u.x * (1. - thetaCos) - u.y * thetaSin) * self.vertices[i].x + (u.z * u.y * (1. - thetaCos) + u.x * thetaSin) * self.vertices[i].y + (thetaCos + u.z.powf(2.) * (1. - thetaCos))    * self.vertices[i].z));
        }
        return Obj { vertices: tempVec, faces: self.faces };

    }

这是在主循环中被调用的方式:

model = model.rotate(0.01 , Vec3::new(0.,1.,0.));

我真的不确定什么是不起作用的。我尝试了不同的矩阵,但失败了。这是我的投影代码:

pub fn perspective(vec: Vec3, camPos: Vec3) -> Vec2 {

    let f = vec.z - camPos.z;

    let new_x = ((vec.x - camPos.x) * (f/vec.z)) + camPos.x;
    let new_y = ((vec.y - camPos.y) * (f/vec.z)) + camPos.y;

    return Vec2::new(new_x, new_y);

}

I've been working a bit on this simple rasterizer, but the cube I imported is not rotating properly. Here's a picture of the issue: enter image description here

I copied a rotation matrix from this Wikipedia page. Here's the rotation function:

    pub fn rotate(self, theta: f32, axis: Vec3) -> Obj {

        let u = Vec3::normalize(axis);
        
        let mut tempVec: Vec<Vec3> = vec![];

        let thetaCos = theta.cos();
        let thetaSin = theta.sin();

        for i in 0..self.vertices.len() {
        tempVec.push(Vec3::new( (thetaCos + u.x.powf(2.) * (1. - thetaCos))    * self.vertices[i].x + (u.x * u.y * (1. - thetaCos) - u.z * thetaSin) * self.vertices[i].y + (u.x * u.z * (1. - thetaCos) + u.y * thetaSin) * self.vertices[i].z,
                                (u.y * u.x * (1. - thetaCos) + u.z * thetaSin) * self.vertices[i].x + (thetaCos + u.y.powf(2.) * (1. - thetaCos))    * self.vertices[i].y + (u.y * u.z * (1. - thetaCos) - u.x * thetaSin) * self.vertices[i].z,
                                (u.z * u.x * (1. - thetaCos) - u.y * thetaSin) * self.vertices[i].x + (u.z * u.y * (1. - thetaCos) + u.x * thetaSin) * self.vertices[i].y + (thetaCos + u.z.powf(2.) * (1. - thetaCos))    * self.vertices[i].z));
        }
        return Obj { vertices: tempVec, faces: self.faces };

    }

And here's how it gets called in the main loop:

model = model.rotate(0.01 , Vec3::new(0.,1.,0.));

I'm really not sure what isn't working. I tried a different matrix and it failed even worse. Here's my projection code:

pub fn perspective(vec: Vec3, camPos: Vec3) -> Vec2 {

    let f = vec.z - camPos.z;

    let new_x = ((vec.x - camPos.x) * (f/vec.z)) + camPos.x;
    let new_y = ((vec.y - camPos.y) * (f/vec.z)) + camPos.y;

    return Vec2::new(new_x, new_y);

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九公里浅绿 2025-02-19 08:10:48

从我的角度投射中,这最终成为一个问题。这是对我有用的代码:

pub fn perspective(vec: Vec3, camPos: Vec3, fov: f32) -> Vec2 {

    let camDist = Vec3::length(camPos - vec);
    let pixel_x = fov*vec.x/(camDist-vec.z);
    let pixel_y = fov*vec.y/(camDist-vec.z);
    return Vec2::new(pixel_x, pixel_y);
}

信用@johnalexiou获得巨大的帮助。

It ended up being an issue with my perspective projection. This is the code that worked for me:

pub fn perspective(vec: Vec3, camPos: Vec3, fov: f32) -> Vec2 {

    let camDist = Vec3::length(camPos - vec);
    let pixel_x = fov*vec.x/(camDist-vec.z);
    let pixel_y = fov*vec.y/(camDist-vec.z);
    return Vec2::new(pixel_x, pixel_y);
}

Credit to @JohnAlexiou for the massive help.

无戏配角 2025-02-19 08:10:48

正如我在评论中所说的那样,当数学签出时,问题与旋转并不是在旋转。

问题应该与投影有关。

这是透视预测的几何形状。下面是侧面的草图,显示了 y z 坐标的相互作用。 x z 坐标之间也发生了类似的事情,

“

给定点 p ,带有(x,y,z)坐标,您想找到点 q ,这是模型平面上的投影。

更具体地说,您需要找到距离 QC 并将其作为距离 ab 的比率。这是因为在屏幕上,距离 ab 对应于视口像素中的高度 h

因此,垂直像素计数是

          y     L
py = H * --- * ---
         AB    L-z

l 是沿 z z 轴的相机/眼睛的距离。

有时,型号尺寸 ab 尚不清楚,而是以度为单位的视野(FOV)。从三角学来看,我们具有 tan(fov/2*π/180)= ab/(2*l),它简化了投影,因为

                 1          y
py = H * -------------- *  ---
         tan(fov*π/360)    L-z

通常是因子 f = h/tan(fov*) π/360)是预先计算的,点的投影 p

px = f * (x/(L-z))
py = f * (y/(L-z))

As I stated in the comments the issue is not with the rotation as the math checks out.

The issue should be with the projection.

Here is the geometry for the perspective projections. Below is a sketch from the side showing how y and z coordinates interact. Something similar happens between the x and z coordinates as well

fig1

Given a point P with (x,y,z) coordinates, you want to find point Q which is the projection on the model plane.

More specifically you need to find the distance QC and relate it as a ratio to the distance AB. This is because on screen the distance AB corresponds to the height H in pixels of your viewport.

So the vertical pixel count is

          y     L
py = H * --- * ---
         AB    L-z

where L is the distance to the camera/eye along the z axis.

Sometimes the model size AB isn't known, but instead the field of view (FOV) in degrees is. From trigonometry, we have tan(fov/2*π/180) = AB/(2*L) which simplifies the projection as such

                 1          y
py = H * -------------- *  ---
         tan(fov*π/360)    L-z

Typically the factor f=H/tan(fov*π/360) is pre-computed and the projection of point P is

px = f * (x/(L-z))
py = f * (y/(L-z))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文