2D声音游戏开发:如何获取相机视角向量并计算与物体夹角?
问题描述
我用Python 3开发一款2D声音游戏,玩家可在2D空间内行走并感知空间中物体的声音。
已通过Supercollider的Ambisonics-toolkit实现声音空间化:相对于玩家视角,0代表前方,-π为逆时针方向后方,π为顺时针方向后方。
我已掌握两向量夹角的计算方法,但无法从玩家位置、物体位置及玩家视角角度得到所需的两个向量,恳请帮助。
更新1
我使用以下函数:
# by: Alex Martelli def dotproduct(v1, v2): return sum((a*b) for a, b in zip(v1, v2)) def length(v): return math.sqrt(dotproduct(v, v)) def angle(v1, v2): return math.acos(dotproduct(v1, v2) / (length(v1) * length(v2))) # by me def subtractVectors(v1,v2): x1 = v1[0] y1 = v1[1] x2 = v2[0] y2 = v2[1] x3 = x1 - x2 y3 = y1 - y2 return [x3, y3]
另外,Supercollider中Ambisonics转换器的文档如下,供参考:
FoaPush.ar(in, angle: 0, theta: 0, phi: 0, mul: 1, add: 0) Arguments: in The B-format signal, an array: [w, x, y, z] angle The distortion angle, in radians. -pi/2 to pi/2 theta Azimuth, in radians. phi Elevation, in radians. mul Output will be multiplied by this value. add This value will be added to the output.
我认为我仅需调制theta参数。
解决方案
要获取计算所需的两个向量,逻辑很清晰:
玩家朝向向量
设玩家视角角度为player_angle:- 若你的2D空间是常规笛卡尔坐标系(x向右,y向上),玩家前方(角度0)的向量为
(math.cos(player_angle), math.sin(player_angle)) - 若为游戏常用的y轴向下坐标系,向量改为
(math.cos(player_angle), -math.sin(player_angle))
- 若你的2D空间是常规笛卡尔坐标系(x向右,y向上),玩家前方(角度0)的向量为
玩家指向物体的向量
直接用你写的subtractVectors函数,传入物体位置object_pos和玩家位置player_pos,得到的结果就是从玩家指向物体的方向向量:vec_to_object = subtractVectors(object_pos, player_pos)
直接计算theta参数的优化方法
用math.atan2能直接算出带方向的相对角度,比余弦夹角更准确,还能自动处理正负方向:
import math def calculate_theta(player_pos, object_pos, player_angle): # 计算玩家到物体的向量 vec_to_obj = subtractVectors(object_pos, player_pos) # 计算该向量在全局坐标系中的绝对角度 obj_global_angle = math.atan2(vec_to_obj[1], vec_to_obj[0]) # 计算相对于玩家视角的方位角 theta = obj_global_angle - player_angle # 将角度归一到[-π, π]范围 theta = math.atan2(math.sin(theta), math.cos(theta)) return theta
这个函数返回的theta可以直接传给Supercollider的FoaPush.ar的theta参数,完全匹配你的空间化需求。
内容的提问来源于stack exchange,提问作者nammedit
相关产品推荐
相关产品推荐

