मैं एक परिपत्र गति के साथ वस्तु को कैसे बाधित कर सकता हूं


23

मैं एक 2d स्पेस गेम बना रहा हूं और स्पेसशिप को एक ग्रह को इंटरसेप्ट करने की जरूरत है। मेरे पास स्ट्रेट लाइन इंटरसेप्ट्स के लिए वर्किंग कोड है, लेकिन यह पता नहीं लगा सकते हैं कि एक गोलाकार कक्षा में ग्रहों की स्थिति की गणना कैसे की जाए।

खेल वैज्ञानिक रूप से सटीक नहीं है, इसलिए मैं जड़ता, गुरुत्वाकर्षण, अण्डाकार कक्षाओं आदि के बारे में चिंतित नहीं हूं।

मैं अंतरिक्ष यान स्थान और गति और ग्रहों की कक्षा (त्रिज्या) और गति को भी जानता हूं

यहाँ छवि विवरण दर्ज करें


1
नहीं, मैं उस कोण की गणना करने की कोशिश कर रहा हूं जो ग्रह को बाधित करने के लिए जहाज को स्थानांतरित करने की आवश्यकता है।
अनुसा

4
यह शायद math.stackexchange.com में बेहतर काम करेगा ..
जरी कोप्पा

2
क्या आपका जहाज गति और दिशा बदलने में सक्षम है, या वे स्थिर हैं? इसके अलावा, मिसाइलों के गोल से बचने के बारे में यह सवाल मददगार हो सकता है।
thegrinner

4
स्पष्ट करने के लिए, स्थिति है? ग्रह के लिए दिया गया: कक्षा केंद्र, कक्षा त्रिज्या, कोणीय गति, वर्तमान स्थान; के लिए जहाज : वर्तमान स्थान, वर्तमान गति; ग्रह के अवरोधन के लिए जहाज की गति की दिशा निर्धारित करना
आकाशवाणी

6
एक दिलचस्प ऐतिहासिक नोट के रूप में: ग्रह आमतौर पर अपनी कक्षा के समान दिशा में घूमते हैं, इसलिए यह उत्तरी गोलार्ध के ऊपर से देखे जाने के कारण एंटीक्लॉकवाइज भी है। इस तथ्य से हम यह अनुमान लगा सकते हैं कि उत्तरी गोलार्ध में sundials का आविष्कार किया गया था । अगर दक्षिणी गोलार्ध में sundials का आविष्कार किया गया था, तो दक्षिणावर्त दूसरा रास्ता होगा।
एरिक लिपर्ट

जवाबों:


3

इसके लिए एक विश्लेषणात्मक समाधान मुश्किल है, लेकिन हम आवश्यक सटीकता के भीतर समाधान खोजने के लिए बाइनरी खोज का उपयोग कर सकते हैं ।

जहाज समय पर कक्षा में निकटतम बिंदु तक पहुँच सकता है t_min :

shipOrbitRadius = (ship.position - planet.orbitCenter).length;
shortestDistance = abs(shipOrbitRadius - planet.orbitRadius);
t_min = shortestDistance/ship.maxSpeed;

जहाज t_max के बराबर या उससे कम समय में कक्षा के किसी भी बिंदु तक पहुँच सकता है :

(यहाँ, सादगी के लिए, मुझे लगता है जहाज सूरज के माध्यम से ड्राइव कर सकते हैं। आप इस से बचने के लिए तो आप कम से कम कुछ मामलों के लिए गैर-सरल-रेखा पथ करने के लिए स्विच करने की आवश्यकता होगी चाहते हैं। "चुंबन हलकों" अच्छा और कक्षीय लग सकता है यांत्रिकी-y, एक स्थिर कारक से अधिक एल्गोरिथ्म को बदले बिना)

if(shipOrbitRadius > planet.orbitRadius)
{
   t_max = planet.orbitRadius * 2/ship.maxSpeed + t_min;
}
else
{
   t_max = planet.orbitRadius * 2/ship.maxSpeed - t_min;
}

यदि हमारी कक्षीय अवधि कम है, तो हम इस ऊपरी सीमा पर सुधार करने में सक्षम हो सकते t_maxहैं कि पहली बार चुनने के बाद t_minग्रह जहाज की शुरुआत की स्थिति के लिए अपना निकटतम दृष्टिकोण बनाता है। इन दोनों में से जो भी मान लें t_maxवह छोटा है। यह क्यों काम करता है की एक व्युत्पत्ति के लिए बाद में इसका जवाब देखें।

अब हम इन चरम सीमाओं, t_min और t_max के बीच द्विआधारी खोज का उपयोग कर सकते हैं । हम एक ऐसे टी-मान की खोज करेंगे जिसमें त्रुटि शून्य के करीब हो:

error = (planet.positionAtTime(t) - ship.position).squareMagnitude/(ship.maxSpeed*ship.maxSpeed) - t*t;

(इस निर्माण का उपयोग करते हुए, त्रुटि @ t_min> = 0 और त्रुटि @ t_max <= 0, इसलिए त्रुटि के साथ कम से कम एक अवरोधन होना चाहिए = बीच में एक टी-मान के लिए =

जहां, पूर्णता के लिए, स्थिति फ़ंक्शन कुछ इस तरह है ...

Vector2 Planet.positionAtTime(float t)
{
  angle = atan2(startPosition - orbitCenter) + t * orbitalSpeedInRadians;
  return new Vector2(cos(angle), sin(angle)) * orbitRadius + orbitCenter;
}

ध्यान दें कि यदि जहाज की गति की तुलना में ग्रह की कक्षीय अवधि बहुत कम है, तो यह त्रुटि फ़ंक्शन t_min से t_max तक की अवधि में कई बार संकेत बदल सकता है। बस जल्द से जल्द + ve & -ve जोड़ी पर नज़र रखें, और उनके बीच खोज जारी रखें जब तक कि त्रुटि शून्य के करीब न हो ("पर्याप्त पास" आपकी इकाइयों और गेमप्ले संदर्भ के प्रति संवेदनशील हो। आधा फ्रेम अवधि का वर्ग हो सकता है। अच्छी तरह से काम - यह सुनिश्चित करता है कि अवरोधन एक फ्रेम के भीतर सटीक है)

एक बार जब आपके पास एक अच्छा त्रुटि-कम करने वाला टी होता है, तो आप केवल जहाज को planet.positionAtTime (t) पर इंगित कर सकते हैं और पूर्ण गला घोंटकर जा सकते हैं, विश्वास है कि ग्रह उस बिंदु पर उसी समय तक पहुंच जाएगा जब आप करते हैं।

आप हमेशा Log_2 ((2 * orbitRadius / ship.maxSpeed) / errorThreshold) पुनरावृत्तियों के भीतर एक समाधान पा सकते हैं। इसलिए, उदाहरण के लिए, यदि मेरा जहाज 60 फ्रेम में कक्षा को पार कर सकता है, और मुझे एक फ्रेम के भीतर एक अवरोधन चाहिए, तो मुझे लगभग 6 पुनरावृत्तियों की आवश्यकता होगी।


1
यहाँ बहुत सारे अच्छे जवाब हैं, कुछ दिलचस्प वैकल्पिक विकल्प भी हैं, लेकिन मेरे पास जो पहले से ही यह समाधान था, वह मेरे उदाहरण के लिए सबसे अच्छा लग रहा है। मैंने अपने परिणामों का एक छोटा जावास्क्रिप्ट डेमो बनाया है। डेमो
औसा

11

आइए इसे अधिक जटिल न करें। यह एक "सही" समाधान नहीं है, लेकिन अधिकांश खेलों के लिए काम करना चाहिए और किसी भी अपूर्णता को खिलाड़ी के लिए अदृश्य होना चाहिए।

if(!OldTargetPoint)
  TargetPoint = PlanetPosition;
else
  TargetPoint = OldTargetPoint;
Distance = CurPosition - TargetPoint;
TimeNeeded = Distance / Speed;
TargetPoint = PlanetPositionInFuture(TimeNeeded);
SteerTowards(TargetPoint);
[...repeat this every AI update, for example every second...]
  1. लक्ष्य बिंदु तक पहुंचने के लिए आवश्यक समय की गणना करें।
  2. गणना समय पर ग्रह किस स्थिति में होगा, इसकी गणना करें।
  3. परिकलित बिंदु की ओर बढ़ें।
  4. दोहराना

यह काम करता है क्योंकि अंतरिक्ष यान जितना निकट होता है उतनी कम त्रुटि होती है। इसलिए समय के साथ गणना अधिक स्थिर हो जाती है।

त्रुटि ग्रह तक पहुंचने के लिए गणना किए गए आवश्यक समय (टाइमनेड) और ग्रह तक पहुंचने के लिए आवश्यक वास्तविक समय (नए टारगेट को ध्यान में रखने के बाद) के बीच का अंतर है।


1
आप इंटरसेप्ट कोर्स शुरू करते समय इसके 2 पुनरावृत्तियों को चलाना चाह सकते हैं, अन्यथा आप दो दिशाओं के बीच जहाज को टिमटिमाते हुए देख सकते हैं (दूसरा अनुमान पहले की तुलना में बहुत बेहतर हो सकता है, और बहुत अलग शीर्षक में परिणाम हो सकता है - खासकर यदि जहाज करने के लिए या ग्रह की कक्षा के अंदर) के करीब है
DMGregory

1
@DMGregory ओह! हम प्रारंभिक बिंदु के रूप में ऑर्बिट सेंटर के बजाय ग्रह की वर्तमान स्थिति ले सकते हैं। जब हम करीब होते हैं तो बहुत करीब होते हैं, अगर हम बहुत दूर होते हैं तो कोई फर्क नहीं पड़ता।
एपीआई-बीस्ट

यह भी ध्यान देने योग्य है कि यह सबसे अच्छा काम करता है जब ग्रह जहाज की तुलना में धीरे-धीरे चलता है। यदि ग्रह की गति जहाज की तुलना में या उससे अधिक है, तो आप जहाज के मार्ग में दोलन देख सकते हैं। पैथोलॉजिकल गति अनुपात में, जहाज एक केंद्रित कक्षा पर हमेशा के लिए ग्रह का पीछा कर सकता है। यदि आपके ग्रह तेज़ हैं और आपको ऐसा हो रहा है, तो हो सकता है कि आप मध्य-उड़ान को ध्यान में रखते हुए अपने पूरे इंटरसेप्‍ट कोर्स को अप-फ्रंट की योजना बनाना चाहें।
DMGregory

3

समस्या के पीछे के गणित पर एक नज़र डालकर शुरू करते हैं।

चरण 1:

एक रेखा और आकृति के बीच के चौराहे को खोजना केवल आकृति के समीकरण में रेखा के समीकरण को सम्मिलित करने का एक मामला है, जो इस मामले में एक चक्र है।

सर्कल के साथ प्रतिच्छेद रेखा

केंद्र c और त्रिज्या r के साथ एक वृत्त लें । यदि सर्कल पर एक बिंदु p है

|pc|2=r2

रूप में व्यक्त की गई एक पंक्ति के साथp=p0+μv

|p0+μvc|2=r2

वर्ग दूरी को डॉट उत्पाद ( http://en.wikipedia.org/wiki/Dot_product ) के रूप में फिर से लिखा जा सकता है ।

(p0+μvc)(p0+μvc)=r2

a=cp0(μva)(μva)=r2

μ2(vv)2μ(av)+aa=r2

|v|=1

μ22μ(av)+|a|2r2=0

जो एक सरल द्विघात समीकरण है, और हम समाधान पर पहुंचते हैं

μ=av+sqrt((av)2a2r2)

अगर μ<0

अगर μ=0

μ

चरण 2:

इसलिए हम जहाज के लिए एक लाइन परिभाषित कर सकते हैं, और उसमें से हम 0, 1 या 2 प्राप्त करते हैं μ

इससे हम क्या कर सकते हैं? खैर, अब हम जानते हैं कि जहाज को कितनी दूरी तय करनी है और वह किस बिंदु पर समाप्त होगा!

p=p0+μvμv

अब, जो कुछ करना बाकी है, वह गणना करना है कि ग्रह कहाँ होना चाहिए जब जहाज की कक्षा की ओर आना शुरू हो। यह आसानी से तथाकथित पोलर कूडेनेट्स ( http://mathworld.wolfram.com/PolarCoordinates.html ) से गणना की जाती है

x=c+rcos(θ)

y=c+rsin(θ)

tangularVelocity

सारांश

अपने जहाज के लिए एक लाइन चुनें, और यह देखने के लिए गणित चलाएं कि क्या यह ग्रहों की कक्षा से टकराता है। यदि ऐसा होता है, तो उस बिंदु पर पहुंचने के लिए लगने वाले समय की गणना करें। इस समय का उपयोग इस बिंदु से कक्षा में वापस जाने के लिए ग्रह के साथ गणना करने के लिए करें कि जहाज कहाँ चलना शुरू होता है।


8
अच्छा विश्लेषण, लेकिन यह सवाल का जवाब नहीं देता है (एक टिप्पणी में स्पष्ट किया गया है): "नहीं, मैं ग्रह को बाधित करने के लिए जहाज को स्थानांतरित करने के लिए कोण की गणना करने की कोशिश कर रहा हूं।" आप जहाज के कोण को एक दिए गए ग्रह के रूप में ले रहे हैं और ग्रह की स्थिति की गणना कर रहे हैं, बजाय अन्य तरीके से।
शाम

4
इसका विश्लेषण करने के लिए नहीं जा रहा है क्योंकि यह उपयोगी विश्लेषण है, लेकिन मैं @ Chaosed0 से सहमत हूं कि यह सवाल का जवाब नहीं देता है। अपने सारांश में आप कहते हैं कि "अपने जहाज के लिए एक लाइन चुनें ..." लेकिन उस लाइन को चुनना बिल्कुल कठिन हिस्सा है।
ड्रेक

1

यहाँ दो "बॉक्स से बाहर" समाधान हैं।

सवाल यह है: यह देखते हुए कि जहाज किसी दिए गए वेग पर एक सीधी रेखा में चलता है, और ग्रह किसी दिए गए कोणीय वेग पर दिए गए त्रिज्या के एक चक्र में चलता है, और ग्रह और जहाज की शुरुआती स्थिति, यह निर्धारित करता है कि जहाज किस दिशा में है इंटरसेप्ट कोर्स को प्लॉट करने के लिए स्ट्रेट लाइन होनी चाहिए।

समाधान एक: प्रश्न के आधार से इनकार करें। प्रश्न में "फिसलन" की मात्रा कोण है। इसके बजाय, इसे ठीक करें। कक्षा के केंद्र में सीधे जहाज को इंगित करें।

  • उस स्थिति की गणना करें जिस पर जहाज ग्रह का सामना करेगा; यह आसान है।
  • जहाज से अवरोधन की स्थिति की दूरी की गणना करें; आसान भी है।
  • उस समय की गणना करें जब तक कि ग्रह अगले अवरोधन की स्थिति तक नहीं पहुंच जाता। आसान।
  • जहाज से अवरोधन की दूरी को उस समय तक विभाजित करें जब तक कि ग्रह को अवरोधन नहीं मिल जाता।
  • यदि वह जहाज की अधिकतम गति से छोटा या उसके बराबर है, तो आप कर रहे हैं। उस गति से चलते हुए जहाज को सीधे सूर्य की ओर सेट करें।
  • अन्यथा, ग्रह की कक्षीय अवधि को समय पर जोड़ें और फिर से प्रयास करें। ऐसा तब तक करते रहें जब तक कि आपको एक गति न मिल जाए जो जहाज के लिए कारण है।

समाधान दो: इसे ऑटोपायलट पर बिल्कुल न करें। एक मिनी-गेम बनाएं जहां खिलाड़ी को ग्रह से संपर्क करने के लिए थ्रस्टर्स का उपयोग करना पड़ता है, और अगर वे इसे बहुत अधिक गति से टकराते हैं, तो वे उड़ जाते हैं, लेकिन उनके पास सीमित ईंधन भी है। इंटरसेप्ट समस्या को हल करने के लिए खिलाड़ी को सीखें!


1

यदि आप ध्रुवीय निर्देशांक का उपयोग नहीं करना चाहते हैं, तो विचार करें कि जहाज के सभी संभावित पदों में शंकु है (एक्स,y,टी)अंतरिक्ष। इसके लिए समीकरण है

टीv=एक्स2+y2

कहा पे vजहाज का वेग है। यह माना जाता है कि जहाज शून्य से शुरू होता है।

अंतरिक्ष और समय में ग्रह की स्थिति को उदाहरण के लिए पैरामीट्रिक किया जा सकता है

एक्स=एक्स0+आरसीरों(wयू+)y=y0+आररोंमैंn(wयू+)टी=यू

कहा पे यू से चला जाता है 0 ऊपर की ओर। w कोणीय गति और है शून्य पर ग्रह का शुरुआती कोण है। फिर हल करें जहां जहाज और ग्रह समय और स्थान में मिल सकते हैं। आप के लिए एक समीकरण मिलता हैयू समाधान करना:

uv=(x0+rcos(wu+a))2+(y0+rsin(wu+a))2u2v2=(x0+rcos(wu+a))2+(y0+rsin(wu+a))2u2v2=x02+y02+r2+2x0rcos(wu+a)+2y0rsin(wu+a)

This equation needs to be solved numerically. It may have many solutions. By eyeballing it, it seems it always has a solution


1

Here's part of a solution. I didn't get to finish it in time. I'll try again later.

If I understand correctly, you have a planet's position & velocity, as well as a ship's position and speed. You want to get the ship's movement direction. I'm assuming the ship's and planet's speeds are constant. I also assume, without loss of generality, that the ship is at (0,0); to do this, subtract the ship's position from the planet's, and add the ship's position back onto the result of the operation described below.

Unfortunately, without latex, I can't format this answer very well, but we'll attempt to make do. Let:

  • s_s = the ship's speed (s_s.x, s_s.y, likewise)
  • s_a = the ship's bearing (angle of movement, what we want to calculate)
  • p_p = the planet's initial position, global coords
  • p_r = the planet's distance (radius) from the center of orbit, derivable from p_p
  • p_a = the planet's initial angle in radians, relative to the center of orbit
  • p_s = the planet's angular velocity (rad/sec)
  • t = the time to collision (this turns out to be something we must calculate as well)

Here's the equations for the position of the two bodies, broken down into components:

ship.x = s_s.x * t * cos(s_a)
ship.y = s_s.y * t * sin(s_a)

planet.x = p_r * cos(p_a + p_s * t) + p_p.x
planet.y = p_r * sin(p_a + p_s * t) + p_p.y

Since we want ship.x = planet.x and ship.y = planet.y at some instant t, we obtain this equation (the y case is nearly symmetrical):

   s_s.x * t * cos(s_a) = p_r * cos(p_a + p_s * t) + p_p.x
   s_s.y * t * sin(s_a) = p_r * sin(p_a + p_s * t) + p_p.y

Solving the top equation for s_a:

   s_s.x * t * cos(s_a) = p_r * cos(p_a + p_s * t) + p_p.x
=> s_a = arccos((p_r * cos(p_a + p_s * t) + p_p.x) / (s_s.x * t))

Substituting this into the second equation results in a fairly terrifying equation that Wolfram alpha won't solve for me. There may be a better way to do this not involving polar coordinates. If anyone wants to give this method a shot, you're welcome to it; I've made this a wiki. Otherwise, you may want to take this to the Math StackExchange.


2
I would love to have TeX enabled for this site. It would make some graphics related stuff (e.g. vector, matrices, quaternions..) easier to represent.
mvw

0

I would fix the location at which to intercept (graze the circle, at the "outgoing" side of the orbit.)

Now you just have to adjust the spaceship's speed so that planet and ship reach that point at the same time.

Note that the rendez-vous could be after N more orbits, depending how far away the ship is, and how fast the planet is orbiting the star.

Pick the N that in time, comes nearest to the ship's journey duration at current speed.

Then speed up or slow down ship to match the timestamp for those N orbits exactly.

In all this, the actual course is already known! Just not the speed.


This could give unnecessarily long trips. Let's say we're positioned so that the planet is coming toward us and we can actually reach the "incoming" grazing point at the same time the planet does. If we're only looking at the "outgoing" grazing point, then we could end up spending half an extra half a year in transit!
DMGregory

True... depends on orbital speeds. But it also minimizes the delta-speed if you always graze at outgoing. At "incoming" you could burn up in the atmosphere, whereas in "outgoing" you are more likely to be matched. @DMGregory
Bram
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.