कम शक्ति वाले हार्डवेयर पर परिपत्र गति


10

मैं प्लेटफार्मों और दुश्मनों के बारे में सोच रहा था पुराने 2 डी गेम में हलकों में चल रहा था, और मैं सोच रहा था कि यह कैसे किया गया था। मैं पैरामीट्रिक समीकरणों को समझता हूं, और यह करने के लिए पाप और कॉशन का उपयोग करना तुच्छ है, लेकिन क्या कोई एनईएस या एसएनईएस वास्तविक समय ट्रिगर कॉल कर सकता है? मैं भारी अज्ञानता स्वीकार करता हूं, लेकिन मुझे लगा कि वे महंगे ऑपरेशन थे। क्या उस गति को अधिक सस्ते में गणना करने के लिए कुछ चतुर तरीका है?

मैं ट्रिगर योग पहचानों से एक एल्गोरिथ्म प्राप्त करने पर काम कर रहा हूं जो केवल पूर्व-निर्धारित ट्रिगर का उपयोग करेगा, लेकिन यह जटिल लगता है।


1
मुझे वास्तव में यह सवाल कई साल पहले एक नौकरी के साक्षात्कार के दौरान पूछा गया था।
क्रेशवर्क्स

जवाबों:


14

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

इस तकनीक के साथ संभावित मुद्दा यह है कि यह मेमोरी स्पेस की खपत करता है, हालांकि आप इसे अपनी तालिका में डेटा के कम रिज़ॉल्यूशन के लिए निपटाकर या कम डेटा स्टोर करने के लिए कुछ कार्यों की आवधिक प्रकृति का लाभ उठाकर और इसे रनटाइम पर मिरर कर सकते हैं।

हालांकि, विशेष रूप से ट्रैवर्सिंग सर्कल के लिए - या तो उन्हें रिस्ट्रिक्ट करने के लिए या किसी एक के साथ कुछ स्थानांतरित करने के लिए, ब्रेसेनहैम की रेखा एल्गोरिथ्म का एक भिन्नता नियोजित किया जा सकता हैब्रेसेनहैम का वास्तविक एल्गोरिदम , निश्चित रूप से, उन ट्रैवर्सिंग लाइनों के लिए भी उपयोगी है जो आठ "प्राथमिक" दिशाओं में काफी सस्ते में नहीं हैं।


2
सच्ची कहानी। LUT और एक सर्कल को 256 डिग्री पैदावार सस्ते ट्रिगर के रूप में परिभाषित किया गया है, मिररिंग केवल तभी किया गया था जब मेमोरी तंग थी और कुछ बाइट्स प्राप्त करने के लिए अंतिम उपाय के रूप में। ब्रेसेनहैम संदर्भ अलग-अलग आंदोलन के लिए भी हाजिर है।
पैट्रिक ह्यूजेस

4
आधुनिक हार्डवेयर पर भी, एक ट्रिगर कॉल अभी भी एक लुकअप टेबल है। यह टेलर के विस्तार के माध्यम से कुछ शोधन के साथ हार्डवेयर में सिर्फ एक लुकअप टेबल है। (वास्तव में एक प्रमुख कंसोल निर्माता का SIMD पाप () फ़ंक्शन का कार्यान्वयन केवल एक हार्डकोड टेलर श्रृंखला है।)
क्रैशवर्क्स

3
@ क्रशवर्क्स: टेलर सीरीज़ का कोई तरीका नहीं है, यह वास्तव में उनके लिए बेवकूफी होगी। यह शायद एक न्यूनतम बहुपद है। वास्तव में, पाप के सभी आधुनिक कार्यान्वयन () जो मैंने कभी देखे हैं, वे मिनिमैक्स पॉलीओनियल पर आधारित हैं।
सैम होसेवर

@SamHocevar हो सकता है। मैंने सिर्फ ax + bx ^ 3 + cx ^ 5 + ... का योग देखा और "टेलर श्रृंखला" ग्रहण की।
क्रैशवर्क्स

9

जेम्स फ्रिथ द्वारा ब्रेसेनहैम के एल्गोरिथ्म की भिन्नता है , जो कि और भी तेज होनी चाहिए क्योंकि यह पूरी तरह से गुणन को समाप्त करता है। इसे प्राप्त करने के लिए किसी भी लुकअप तालिका की आवश्यकता नहीं है, हालांकि यदि त्रिज्या स्थिर रहती है तो कोई परिणाम तालिका में संग्रहीत कर सकता है। चूंकि ब्रेसेनहैम और फ्रिथ के एल्गोरिथ्म दोनों 8-गुना समरूपता का उपयोग करते हैं, इसलिए यह लुकअप तालिका अपेक्षाकृत कम होगी।

// FCircle.c - Draws a circle using Frith's algorithm.
// Copyright (c) 1996  James E. Frith - All Rights Reserved.
// Email:  jfrith@compumedia.com

typedef unsigned char   uchar;
typedef unsigned int    uint;

extern void SetPixel(uint x, uint y, uchar color);

// FCircle --------------------------------------------
// Draws a circle using Frith's Algorithm.

void FCircle(int x, int y, int radius, uchar color)
{
  int balance, xoff, yoff;

  xoff = 0;
  yoff = radius;
  balance = -radius;

  do {
    SetPixel(x+xoff, y+yoff, color);
    SetPixel(x-xoff, y+yoff, color);
    SetPixel(x-xoff, y-yoff, color);
    SetPixel(x+xoff, y-yoff, color);
    SetPixel(x+yoff, y+xoff, color);
    SetPixel(x-yoff, y+xoff, color);
    SetPixel(x-yoff, y-xoff, color);
    SetPixel(x+yoff, y-xoff, color);

    balance += xoff++;
    if ((balance += xoff) >= 0)
        balance -= --yoff * 2;

  } while (xoff <= yoff);
} // FCircle //

यदि आपको अजीब परिणाम मिल रहे हैं, तो ऐसा इसलिए है क्योंकि आप अपरिभाषित (या कम से कम अनिर्दिष्ट) व्यवहार कर रहे हैं । C ++ निर्दिष्ट नहीं करता है कि "ए () + बी ()" का मूल्यांकन करते समय सबसे पहले किस कॉल का मूल्यांकन किया जाता है, और आगे इंटीग्रल्स को संशोधित करता है। इससे बचने के लिए, एक चर को उसी अभिव्यक्ति में संशोधित न करें, जिस रूप में आपने इसे पढ़ा है xoff++ + xoffऔर --yoff + yoff। आपका चेंजलॉजिस्ट इसे ठीक करेगा, नोट पर एक सौदे के रूप में इसके स्थान पर इसे ठीक करने पर विचार करें। (उदाहरणों के लिए C ++ मानक का खंड 5 पैराग्राफ 4 देखें और जो मानक इसे स्पष्ट रूप से कहता है)
MaulingMonkey

@MaulingMonkey: आप की समस्या पैदा करने वाले मूल्यांकन आदेश के बारे में रहे हों तो सही balance += xoff++ + xoffऔर balance -= --yoff + yoff। मैंने इसे अपरिवर्तित छोड़ दिया, क्योंकि यह जिस तरह से फ्रिथ के एल्गोरिथ्म को मूल रूप से लिखा गया था, ठीक करने के साथ बाद में खुद को जोड़ा गया ( यहां देखें )। अभी तय किया है।
पैगंबर जु

2

आप टेलर एक्सपैंशन http://en.wikipedia.org/wiki/Tayb_series का उपयोग करके ट्रिग फ़ंक्शंस का एक अनुमानित संस्करण भी उपयोग कर सकते हैं

उदाहरण के लिए, आपके पास पहले चार टेलर श्रृंखला की शर्तों का उपयोग करके साइन का एक उचित अनुमान हो सकता है

ज्या


यह आम तौर पर सच है, लेकिन इतने सारे कैविट्स के साथ आता है कि मैं इतनी दूर तक जाऊंगा कि आपको यह कहना चाहिए कि जब तक आप जो कर रहे हैं उससे बहुत परिचित नहीं हैं। विशेष रूप से, एक सूचीबद्ध, यहां तक ​​कि बेहतर तर्कसंगत अनुमानों की तुलना में (थोड़ा) बेहतर बहुपद हैं, और आपको यह समझने की आवश्यकता है कि सूत्र को लागू करने के लिए और कैसे अपने तर्क को एक सीमा तक सीमित करने के लिए पाप और कोस की आवधिकता का उपयोग करें जहां श्रृंखला लागू होती है। यह उन मामलों में से एक है जहां पुराने कामोन्माद 'थोड़ा ज्ञान एक खतरनाक चीज है' सच है।
स्टीवन स्टैडनिक

क्या आप कुछ संदर्भ दे सकते हैं ताकि मैं इस बहुपद या अन्य बेहतर सन्निकटन सीख सकूं? मैं वास्तव में वह सीखना चाहता हूं। यह सीरीज़ चीज़ मेरे कैलकुलस कोर्स का सबसे ज़्यादा दिमाग उड़ाने वाला हिस्सा था।

शुरू करने के लिए क्लासिक जगह न्यूमेरिकल रेसिपी है, जो कोर संख्यात्मक कार्यों और उनके सन्निकटन के पीछे के गणित की गणना करने के बारे में थोड़ी जानकारी देता है। एक और जगह जिसे आप देख सकते हैं, एक दृष्टिकोण के लिए जो थोड़ा पुराना है लेकिन अभी भी जानने के लायक है, तथाकथित कॉर्डिक एल्गोरिदम को देखना है।
स्टीवन स्टडनिक

@ वांडेल: यदि आप मिनिमैक्स पॉलीनॉमिअल्स बनाना चाहते हैं, तो मुझे लोरेमेज़ के बारे में आपके विचार सुनकर खुशी होगी
सम होसेवर

टेलर श्रृंखला एक बिंदु पर एक फ़ंक्शन के व्यवहार का अनुमान लगाती है, एक अंतराल पर नहीं। बहुपद x = 0 के आसपास पाप (0) या इसके सातवें व्युत्पन्न का मूल्यांकन करने के लिए बहुत अच्छा है, लेकिन x = pi / 2 में त्रुटि, जिसके बाद आप बस दर्पण और दोहरा सकते हैं, काफी बड़ी है। आप इसके बजाय x = pi / 4 के आसपास टेलर श्रृंखला का मूल्यांकन करके लगभग पचास गुना बेहतर कर सकते हैं, लेकिन वास्तव में आप जो चाहते हैं वह एक बहुपद है जो एक बिंदु के पास परिशुद्धता की कीमत पर अंतराल पर अधिकतम त्रुटि को कम करता है।
थॉमस

2

एक सर्कल में समान रूप से यात्रा करने के लिए एक भयानक एल्गोरिथ्म है Goertzel एल्गोरिथ्म । इसके लिए केवल 2 गुणन और 2 जोड़ प्रति चरण, कोई लुकअप तालिका और बहुत न्यूनतम स्थिति (4 नंबर) की आवश्यकता होती है।

पहले आवश्यक कदम आकार (इस मामले में, 2π / 64) के आधार पर, कुछ स्थिरांक, संभवतः हार्डकोड को परिभाषित करें:

float const step = 2.f * M_PI / 64;
float const s = sin(step);
float const c = cos(step);
float const m = 2.f * c;

एल्गोरिथ्म अपने राज्य के रूप में 4 नंबरों का उपयोग करता है, इस तरह से प्रारंभिक:

float t[4] = { s, c, 2.f * s * c, 1.f - 2.f * s * s };

और अंत में मुख्य लूप:

for (int i = 0; ; i++)
{
    float x = m * t[2] - t[0];
    float y = m * t[3] - t[1];
    t[0] = t[2]; t[1] = t[3]; t[2] = x; t[3] = y;
    printf("%f %f\n", x, y);
}

यह तो हमेशा के लिए जा सकता है। यहां पहले 50 अंक दिए गए हैं:

गोएर्टज़ेल एल्गोरिथम

एल्गोरिथ्म निश्चित बिंदु हार्डवेयर पर काम कर सकता है। ब्रेसेनहैम के खिलाफ स्पष्ट जीत सर्कल पर निरंतर गति है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.