如何确保随机生成的速度矢量使相机在有效弧度内向前移动?
How to ensure that a randomly-generated velocity vector moves the camera forward within a valid arc?
我在场景中使用 x
和 y
的随机坐标并设置 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 分量。我改变了那个。 :)
我在场景中使用 x
和 y
的随机坐标并设置 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 分量。我改变了那个。 :)