Bir oyunda (araba yarışı oyunu) doppler etkisini simüle etmeye çalışıyorum. Etkisini simüle eden belirli bir ses kütüphanesi kullanmıyorum, sadece verileri karıştırdığım bir geri arama işlevim var.
Mikser fonksiyonunda bir numunenin frekansının nasıl değiştirileceğini zaten anladım.
Bilmediğim, frekansın ne kadar oynatıcına ve yayıcı konumuna ve hızına bağlı olarak değişmesi gerektiğidir.
İşte oyunda ne var:
//player
vec3 p.pos;
vec3 p.vel;
//emitter
vec3 e.pos;
vec3 e.vel;
1) Vikipedi'ye göre , yayılan frekans ile gözlemlenen frekans arasındaki ilişki şu şekilde verilir:
float f = (c + vr) / (c + vs) * fo
burada C , bir sabit, orta hız (tipik olarak büyük bir sayı) vs ve vr orta görece kaynak ve alıcı hızları.
yani sanırım:
float vr = p.vel.length; //player speed
float vs = e.vel.length; //emitter speed
ama bunun yanlış olduğunu düşünüyorum, örneğin herhangi bir frekans değişikliği üretmeyecek, örneğin: eğer vr = 0
(oyuncu hareket etmiyorsa) ve yayıcı sabit hıza sahipse, o zaman vr
ve vs
değişmeyecekler (gerekirken).
belki oyuncunun hızını yayıcının hızına göre hesaplamalıyım?
bunun gibi :
relative_speed = distance(p.pos + p.vel, e.pos + e.vel) -
distance(p.pos, e.pos);
o zaman nasıl vr
ve nasıl vs
beslenmelidir?
2) wikipedia ayrıca aracın gözlemci tarafından geçtiği bir aracın etkisini simüle etmek için başka bir formül verir:
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); ?
Bununla birlikte, bu formül, alıcının hareket etmediğini varsayar; bu durum böyle değildir. oynatıcı ve verici aynı hızda (veya küçük farkta) hareket ederse, doppler etkisi olmamalıdır. Bu fonksiyon da bir vakaya özgüdür, son formülün durumun aynı olmaması gerektiğini varsayalım.
EDIT: doğru formül bulmaya çalışıyorum, SkimFlux yazı kullanarak:
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:
İlgilenenler için işte son formül:
vec2 dist = vs.pos - vr.pos;
vr,r = dotproduct(vr.vel, dist) / length(dist)
vs,r = dotproduct(vs.vel, dist) / length(dist)
NOT: burada açıklanan vektör projeksiyonu kullanır :
o zaman vr,s
ve vs,r
ilk wikipedia formülüne enjekte edilmelidir:
Test ettim ve harika sonuçlar vererek başarılı bir şekilde çalışıyor.