我无法让顶点围绕玩家正确旋转

I can not get vertices to rotate correctly around a player

我正在使用 C 和 SDL 从头开始​​创建经典射击游戏。我似乎 运行 遇到了一个我想不通的问题。

当我尝试围绕玩家旋转世界几何体时,它似乎没有正确旋转。

理论上玩家和顶点之间的距离在我执行旋转后应该保持不变,但在我的代码中似乎没有。

我在下面包含了我的代码的相关部分以及正在发生的事情的 gif。

我想了解这里发生了什么以及关于如何修复它的一些指导。

for (unsigned s = 0; s < sect->npoints; s++)
{
  // Transform vertex relative to the player view.
  // This will move the room relative to the player.
  float vx1 = sect->vertex[s].x - player.where.x;
  float vx2 = sect->vertex[s+1].x - player.where.x;
  float vy1 = sect->vertex[s].y - player.where.y;
  float vy2 = sect->vertex[s+1].y - player.where.y;

  float test1 = vx1 * vx1 + vy1 * vy1;
  float test2 = vx2 * vx2 + vy2 * vy2;
            
            
  printf("%f %f\n", sqrt(test1), sqrt(test2));
                
  // Rotate the room to the correct orientation using geometry of rotation
  // We want to find t (tx1, tz1) coordinates given the players current orientation.
  // P == player,  v == the vertex in the sector
  // )8 == the angle of the player
  //
  // We can get tx1 = vx1 * player cos - vy1 * player sin
  // and get tz1 = vx1 * player sin - vy1 * player cos
  //  |............................
  // ^|...t (tx1, tz1).............
  // ||../........v (vx1, vy1).....
  // y|./..........................
  // 0|P)8.........................
  //  L-----------------------------
  //   0 x -->
  float pcos = player.anglecos;
  float psin = player.anglesin;
            
  float tx1 = vx1 * psin - vy1 * pcos;
  float tz1 = vx1 * pcos - vy1 * psin;
  float tx2 = vx2 * psin - vy2 * pcos;
  float tz2 = vx2 * pcos - vy2 * psin;

  test1 = tx1 * tx1 + tz1 * tz1;
  test2 = tx2 * tx2 + tz2 * tz2;

  printf("%f %f %f\n\n", sqrt(test1), sqrt(test2), player.angle);

  ...
  // Perform the perspective transformation.
  // This will make sure the correct field of view is being used.
  // TOOD: Adjustible FOV
  float xscale1 = hfov / tz1;
  float yscale1 = vfov / tz1;
  float xscale2 = hfov / tz2;
  float yscale2 = vfov / tz2;

  int x1 = ScreenWidth / 2 - (int)(tx1 * xscale1);
  int x2 = ScreenWidth / 2 - (int)(tx2 * xscale2);
  ...
  int ya = (x - x1) * (y2a-y1a) / (x2-x1) + y1a;
  int yb = (x - x1) * (y2b-y1b) / (x2-x1) + y1b;
                
                
  int cya = clamp(ya, ytop[x], ybottom[x]); // top
  int cyb = clamp(yb, ytop[x], ybottom[x]); // bottom
  rendervline(x, cya, cyb, wall_color);
}

...
// Elsewhere where I handle movement

// mouse aiming
int x, y;
SDL_GetRelativeMouseState(&x,&y);
player.angle += x * 0.03f;

...   
    
player.anglesin = sinf(player.angle);
player.anglecos = cosf(player.angle);

以及玩家与边缘顶点之间距离的一些样本输出。

28.635642 31.304952
29.442936 29.505904 0.070000

我很接近问题是我在计算 z 轴时是减法而不是加法。

  float tx1 = vx1 * psin - vy1 * pcos;
  float tz1 = vx1 * pcos - vy1 * psin;
  float tx2 = vx2 * psin - vy2 * pcos;
  float tz2 = vx2 * pcos - vy2 * psin;

应该是这个

  float tx1 = vx1 * psin - vy1 * pcos;
  float tz1 = vx1 * pcos + vy1 * psin;
  float tx2 = vx2 * psin - vy2 * pcos;
  float tz2 = vx2 * pcos + vy2 * psin;