게임 (자동차 경주 게임)에서 도플러 효과를 시뮬레이션하려고합니다. 효과를 시뮬레이션하는 특정 사운드 라이브러리를 사용하지 않고 데이터를 혼합하는 콜백 기능 만 있습니다.
믹서 기능에서 샘플 주파수를 변경하는 방법을 이미 알아 냈습니다.
내가 모르는 것은 플레이어와 이미 터 위치와 속도에 따라 주파수가 얼마나 바뀌어야 하는가입니다.
게임에서 내가 가진 것은 다음과 같습니다.
//player
vec3 p.pos;
vec3 p.vel;
//emitter
vec3 e.pos;
vec3 e.vel;
1) Wikipedia 에 따르면 방출 주파수와 관측 주파수의 관계는 다음과 같습니다.
float f = (c + vr) / (c + vs) * fo
여기서 C는 상수, 매체의 속도 (일반적으로 큰 수)이고 VS가 및 VR은 매체에 대해 소스 및 수신기 속도이다.
그래서 나는 추측한다 :
float vr = p.vel.length; //player speed
float vs = e.vel.length; //emitter speed
하지만 난 그 잘못은,이 예에 대한 주파수의 변화를 생성 실 거예요 생각 : 경우 vr = 0
(플레이어 해달라고 이동을)과 에미는 일정한 속도로 가지고 vr
와 vs
(있는 동안 그들이해야) 늘 변화.
어쩌면 이미 터의 속도와 상대적으로 플레이어의 속도를 계산해야합니까?
이처럼 :
relative_speed = distance(p.pos + p.vel, e.pos + e.vel) -
distance(p.pos, e.pos);
어떻게 vr
그리고 어떻게 vs
먹어야합니까?
2) 위키 백과 는 또한 차량이 관찰자가 지나가는 차량의 효과를 시뮬레이션하는 또 다른 공식을 제공합니다.
vr = vs * cos(theta);
//theta is angle between observer and emitter
//theta = atan2(e.pos.y-p.pos.y, e.pos.x-p.pos.x); ?
그러나이 공식은 수신기가 움직이지 않는다고 가정하지만 여기에는 해당되지 않습니다. 플레이어와 이미 터가 같은 속도 (또는 작은 차이)로 움직이면 도플러 효과가 없어야합니다. 이 함수는 하나의 경우에만 적용되며, 최종 공식은 상황에 관계없이 동일해야한다고 가정합니다.
편집 : SkimFlux 게시물을 사용하여 올바른 수식을 찾으려고합니다.
vr,r = vr.vel * cos(shortest_angle_between ( vr.vel , vs.pos - vr.pos));
vs,r = vs.vel * cos(shortest_angle_between ( vs.vel , vr.pos - vs.pos));
//is there a easier/faster way to find them out ?
//note: vr.vel and vs.vel are vectors, the green and red arrows on SkimFlux picture.
EDIT2 :
관심있는 사람들을 위해 다음은 최종 공식입니다.
vec2 dist = vs.pos - vr.pos;
vr,r = dotproduct(vr.vel, dist) / length(dist)
vs,r = dotproduct(vs.vel, dist) / length(dist)
참고 : 여기 에 설명 된 벡터 투영을 사용 합니다 .
다음 vr,s
과 vs,r
제 위키 식 주입한다 :
나는 그것을 테스트하고 성공적으로 작동하여 훌륭한 결과를 제공합니다.