Próbuję symulować efekt Dopplera w grze (gra wyścigowa). Nie używam konkretnej biblioteki dźwięków, która symuluje efekt, mam tylko funkcję zwrotną, w której miksuję dane.
Już wymyśliłem, jak zmienić częstotliwość próbki w funkcji miksera.
Nie wiem, jak często częstotliwość powinna się zmieniać w zależności od pozycji i prędkości odtwarzacza i emitera.
Oto co mam w grze:
//player
vec3 p.pos;
vec3 p.vel;
//emitter
vec3 e.pos;
vec3 e.vel;
1) Według Wikipedii związek między częstotliwością emitowaną a częstotliwością obserwowaną podaje:
float f = (c + vr) / (c + vs) * fo
gdzie c jest stałą, prędkość w ośrodku (zwykle duża liczba) vs i vr są prędkościami źródła i odbiornika w stosunku do ośrodka.
zgaduję :
float vr = p.vel.length; //player speed
float vs = e.vel.length; //emitter speed
ale myślę, że to źle, nie spowoduje żadnej zmiany częstotliwości, na przykład: jeśli vr = 0
(gracz nie porusza się) i emiter mają stałą prędkość, to vr
i vs
nie zmieni się (podczas gdy powinny).
może powinienem obliczyć prędkość odtwarzacza w stosunku do prędkości emitera?
lubię to :
relative_speed = distance(p.pos + p.vel, e.pos + e.vel) -
distance(p.pos, e.pos);
jak vr
i jak vs
należy karmić?
2) wikipedia podaje także inną formułę symulującą działanie pojazdu, który pojazd mija obserwatora:
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); ?
jednak ta formuła zakłada, że odbiornik się nie porusza, co nie ma miejsca w tym przypadku. jeśli gracz i emiter poruszają się z tą samą prędkością (lub małą różnicą), nie powinno być efektu dopplerowskiego. ta funkcja jest również specyficzna dla jednego przypadku, przypuszczam, że ostateczna formuła powinna być taka sama bez względu na sytuację.
EDYCJA: próbuję znaleźć poprawną formułę, używając 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.
EDYCJA 2:
Dla zainteresowanych, oto ostateczna formuła:
vec2 dist = vs.pos - vr.pos;
vr,r = dotproduct(vr.vel, dist) / length(dist)
vs,r = dotproduct(vs.vel, dist) / length(dist)
UWAGA: wykorzystuje projekcję wektorową, opisaną tutaj :
wtedy vr,s
i vs,r
powinien zostać wstrzyknięty w pierwszą formułę wikipedii:
Przetestowałem to i działa z powodzeniem, zapewniając świetne wyniki.
Odpowiedzi:
1) Zakłada się, że oba obiekty poruszają się po tej samej linii - (jest to wyjaśnione na stronie, którą połączyłeś na Wikipedii) twój wniosek jest prawidłowy, w tej sytuacji, przy stałych prędkościach, przesunięcie częstotliwości jest stałe. Aby przesunięcie częstotliwości uległo zmianie, prędkości względne muszą się zmienić, stąd wzór 2), w sytuacji, gdy
Vs
jest stały, ale nie współliniowy z osią SR.Wzór 2) jest jednak mylący:
Vr
należy go rozumieć jakoVs,r
składową radialną / względną prędkości źródła.Pamiętaj, że efekt Dopplera zależy tylko od prędkości, potrzebujesz tylko pozycji, aby znaleźć oś SR.
Edycja : to powinno pomóc ci obliczyć prędkości, musisz użyć
Vs,r
iVr,r
ilości w formule 1:źródło
W przypadku XACT należy podać zmienną skalarną skoku dopplerowskiego, tj. Prędkość względną, gdzie 1,0 to ta sama prędkość, ale <1,0 jest wolniejsze, a> 1,0 jest szybsze
Dziękuję wam za kod, który przesłałem do tego fragmentu C #, w którym dźwięk jest obliczany między pozycją ekranu a wskazówką. Działa dokładnie
Btw.
źródło