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

How to ensure that a randomly-generated velocity vector moves the camera forward within a valid arc?

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

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

camera_dir = (0, 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));,即cam方向的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 将始终在所需范围内,表示相机方向与生成的速度方向之间的角度。下图应该说明这种方法:

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