如何确保随机生成的速度矢量在有效弧内向前移动相机?

问题描述

我使用 xy随机坐标并设置 z=0 在场景中生成一个相机,并调整相机的方向,使其看起来在 (0,0) 点上.我的目标是使用地面上随机生成的速度向量向前移动相机(因此 z 保持 0)。我想确保相机的新位置在向前移动后处于有效范围内,以相对于当前焦点/方向的度数定义。更具体地说,我确定“有效范围”的方法是确保新位置在旧相机焦点的 45 度以内(向左 -45 度,向右 +45 度)。有人可以写一段关于我如何实现这一目标的伪代码吗?

这是我的尝试,但这似乎不是帮助我实现我想要的正确方法

camera_dir = (0,0) - current_cam_pos
while True:
    vel_vec=[uniform(-max_vel,max_vel),uniform(-max_vel,max_vel)] # generate a random veLocity vector
    new_pos = camera_dir + vel_vec # compute a new position (and camera direction vector) for the camera
    if (compute_angle(new_pos,camera_dir) < 45 or compute_angle(new_pos,camera_dir) > 315):
        break 

解决方法

您可以使用:

// 45° in rad
double validAngle = Math.PI / 4;

ThreadLocalRandom random = ThreadLocalRandom.current();

Vector2D camPosition = new Vector2D(0,-1);
Vector2D camTarget= new Vector2D(0,0);
Vector2D camDirection = camTarget.subtract(camPosition).normalize();

double cosPhi = camDirection.x;
double phi = Math.acos(cosPhi);
double alpha = random.nextDouble(-validAngle,validAngle);
double angle = phi + alpha;

Vector2D velocity = new Vector2D(Math.cos(angle),Math.sin(angle)).multiply(speed);
Vector2D newPosition = position.add(velocity.multiply(deltaTime));

这种方法是用 Java 编写的,但对于其他语言应该是非常可移植的。

但是,我认为这不是一个完美的解决方案,因为这种方法使用了大量三角函数,这在您必须在每一帧中更新相机的游戏中可能代价高昂。

该方法使用凸轮方向和 x 轴之间的角度以及允许的最大角度来计算最终矢量。首先,我计算凸轮方向和 x 轴之间夹角的余弦并将其命名为 phi。 phi 的余弦为:camDirection.dotProduct(new Vector2D(1,0));,即凸轮方向的 x 分量。因此,假设您的凸轮方向是 (0,1),即 y 轴。那么 phi 是 90°。现在您只需生成一个介于 -45° 和 45° 之间的随机数(将其转换为弧度)并将此角度 alpha 添加到 phi。结果 angle 将在相对于 x 轴的 [135°;45°] 范围内。现在你有了一个相对于 x 轴的角度,并用 (cos(angle),sin(angle)) 计算你的二维向量。您可以测试生成的方向向量是否在允许的最大角度内:

Vector2D newDirection = new Vector2D(Math.cos(angle),Math.sin(angle));

double cosBeta = newDirection.dotProduct(camDirection);
double beta = Math.acos(cosBeta);

beta 将始终在所需范围内,并表示相机方向和生成的速度方向之间的角度。下图应说明此方法: enter image description here

感谢您指出 camDirection.dotProduct(new Vector2D(1,0)); 表示相机方向的 x 分量。我改变了那个。 :)