मैं एक खेल (एक कार रेसिंग खेल) में डॉपलर प्रभाव का अनुकरण करने की कोशिश कर रहा हूं। मैं एक विशिष्ट ध्वनि पुस्तकालय का उपयोग नहीं कर रहा हूं जो प्रभाव का अनुकरण करता है, मेरे पास केवल कॉलबैक फ़ंक्शन है जहां मैं डेटा मिलाता हूं।
मुझे पहले से ही पता चल गया था कि मिक्सर फ़ंक्शन में एक नमूना की आवृत्ति कैसे बदलनी है।
मुझे नहीं पता कि खिलाड़ी और उत्सर्जक स्थिति और वेग के आधार पर आवृत्ति कितनी होनी चाहिए।
यहाँ मैं क्या खेल में है:
//player
vec3 p.pos;
vec3 p.vel;
//emitter
vec3 e.pos;
vec3 e.vel;
1) विकिपीडिया के अनुसार , उत्सर्जित आवृत्ति और देखे गए आवृत्ति के बीच का संबंध निम्न द्वारा दिया गया है:
float f = (c + vr) / (c + vs) * fo
जहाँ c एक स्थिर है, माध्यम में वेग (आमतौर पर एक बड़ी संख्या) बनाम और वीआर स्रोत और रिसीवर के माध्यम से सापेक्ष वेग हैं।
तो मुझे लगता है :
float vr = p.vel.length; //player speed
float vs = e.vel.length; //emitter speed
लेकिन मुझे लगता है कि इसकी गलत है, यह नहीं होते उदाहरण के लिए आवृत्ति में कोई बदलाव, उत्पादन: अगर vr = 0
(खिलाड़ी न चाल) और emitter स्थिर गति है, तो है 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); ?
हालाँकि, इस सूत्र ने माना कि रिसीवर न ले जाएँ, जो यहाँ नहीं है। यदि खिलाड़ी और एमिटर समान गति (या छोटे अंतर) पर चलते हैं, तो कोई डॉपलर प्रभाव नहीं होना चाहिए। यह फ़ंक्शन एक मामले के लिए भी विशिष्ट है, मुझे लगता है कि अंतिम फॉर्मूला वही होना चाहिए जो किसी भी स्थिति में न हो।
संपादित करें: मैं स्किमफ्लक्स पोस्ट का उपयोग करके सही सूत्र खोजने की कोशिश कर रहा हूं:
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
पहले विकिपीडिया सूत्र में इंजेक्ट किया जाना चाहिए:
मैंने इसका परीक्षण किया और यह शानदार तरीके से काम करते हुए शानदार परिणाम प्रदान कर रहा है।