मैं arctan कैसे निपटने चाहिए (और शून्य से deviding रोकने) ARCTAN2 (n, m) उपलब्ध होने की सुविधा के बिना?

वोट
4

मैं एक बिंदु से कोण निर्धारित करने की कोशिश (n,m)करने के लिए (0,0)। बिना arctan2उपलब्ध होने, मैं समस्या यह है कि में चल रहा हूँ m, 0 हो सकता है जो शून्य से एक संभव विभाजन की ओर जाता है।

क्या इस मुद्दे से निपटने के लिए एक सुंदर, सही समाधान हो सकता है?

12/03/2009 को 16:56
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


5 जवाब

वोट
2

पारंपरिक चतुर्थ भाग का उपयोग नहीं करते, रेखाओं द्वारा निर्धारित शाखा अंक का उपयोग y = +/- एक्स, और एक कॉरडिक की तरह एल्गोरिथ्म के 1 दो चरणों का उपयोग करें (उदाहरण के लिए बारी बारी से निर्देशांक एक ज्ञात कोण से और आप कितना का ट्रैक रखने 've घुमाया):

function atan2_substitute(x,y)
{
   double angle = 0;
   if (x < y)
   { angle = M_PI; x = -x; y = -y; }
   // this guarantees that the angle is between -135 and +45 degrees

   if (x < -y)
   {
     angle -= M_PI/2; tmp = x; x = -y; y = tmp;
   }
   // this guarantees that the angle is between -45 and +45

   angle += atan(y/x);

   if (angle > M_PI)
      angle -= 2*M_PI;
   // fails at 0,0; otherwise is accurate over the entire plane
}

यह इस तरह से करने के लिए कारण (कि atan () अधिक, अनुपात y / एक्स के बीच -1 और +1 के लिए सही होने की तुलना में अधिक से अधिक 1. अनुपातों के लिए की तुलना में अधिक संभावना हो सकती है, हालांकि एक अच्छा atan () एल्गोरिथ्म इस पहचान और पारस्परिक लेने के लिए)

12/03/2009 को 17:43
का स्रोत उपयोगकर्ता

वोट
1

मानक लागू arctan(n, m)टेलर श्रृंखला का उपयोग और कंप्यूटिंग arctan से पहले निम्न कार्य करें:

if (m == 0) {
    if (n < 0) return Pi;
    return 0;
}

एक और कुछ गुर:

1) यदि |m| < |n|, स्वैप m, nऔर फिर arctan गणना। अंत में से परिणाम घटानाPi/2

2) यदि |m|के करीब है |n|, आधा कोण आधा कोण सूत्र का उपयोग कर की गणना arctan arctan(x) = 2*arctan(x/(1+sqrt(1+x*x))), अन्यथा, इस तरह के मूल्यों के लिए, arctan बहुत धीरे धीरे अभिमुख

25/01/2010 को 10:46
का स्रोत उपयोगकर्ता

वोट
1

यदि atan2 उपलब्ध नहीं है आप शून्य हालत और अपने कोड में अन्य सभी विशेष मामलों से विभाजन के लिए जाँच करने के लिए है। कि के रूप में आसान। atan2 पर विकिपीडिया प्रविष्टि सभी शर्तों आप की जरूरत है।

अपने लक्ष्य हार्डवेयर बिन्दु आपरेशनों चल के लिए शून्य अपवाद द्वारा विभाजित का समर्थन करता है, तो आप एक और विकल्प है:

एक निम्न स्तर के हैंडलर कि अपवाद कारण की जाँच करता है और अगर यह होने के लिए happends एक atan विभाजन समस्या को ठीक स्थापित करें। यदि अपवाद दुर्लभ हैं यह तेजी से अपने atan2 कर देगा, लेकिन यह निम्न स्तर फेरबदल की आवश्यकता है और पोर्टेबल नहीं है।

12/03/2009 को 17:13
का स्रोत उपयोगकर्ता

वोट
0

मेरा मानना ​​है कि इस atan (हालांकि, infinities संभाल नहीं करता है) का उपयोग कर atan2 का सही कार्यान्वयन है:

float my_atan2(float y, float x)
{
    if(x == 0) // might also want to use fabs(x) < 1e-6 or something like that
    {
        if(y > 0)
            return M_PI_2;
        else
            return -M_PI_2;
    }
    else if(x > 0)
    {
        return atan(y/x);
    }
    else 
    {
        // x < 0                                                                                
        if(y > 0)
            return M_PI + atan(y/x);
        else
            return -M_PI + atan(y/x);
    }
}

दोहन ​​परीक्षण:

int main()
{
    for(int i = -360; i <= 360; i++)
    {
        float x = cos(i / 180.0 * M_PI);
        float y = sin(i / 180.0 * M_PI);


        float good = atan2(y, x);
        float mine = my_atan2(y, x);


        if(fabs(good - mine) > 1e-6)
        {
            printf("%d %f %f %f %f\n", i, x, y, good, mine);
        }
    }
}
12/03/2009 को 17:24
का स्रोत उपयोगकर्ता

वोट
0

के अपने संस्करण को परिभाषित करें arctan2। मैक्रो के रूप में सी में एक उदाहरण:

#define atan2(n,m)   (m)==0 ? M_PI_2 : atan((n)/(m))

बेशक, आप के संकेत के आधार पर वृत्त का चतुर्थ भाग को खोजने के लिए विस्तृत कर सकते हैं nऔर m

12/03/2009 को 17:09
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more