2013-02-14 100 views
8

मेरे खेल के लिए मुझे दो समन्वय प्रणालियों के बीच अनुवाद करने के लिए कार्यों की आवश्यकता है। वैसे यह मुख्य रूप से गणित प्रश्न है, लेकिन मुझे यह करने के लिए सी ++ कोड है और मेरी समस्या को हल करने के लिए कुछ स्पष्टीकरण है।कार्टेशियन और स्क्रीन निर्देशांक के बीच अनुवाद

स्क्रीन coordiantes:

क) ऊपर बाएं कोने है 0,0

ख) कोई शून्य मान

ग) सही + = एक्स (अधिक है एक्स मूल्य, के बारे में अधिक सही बिंदु)

घ) नीचे + = y है

कार्तीय 2 डी निर्देशांक:

क) मध्य बिंदु है (0, 0)

ख) शून्य मान मौजूद है

ग) सही + = एक्स

घ) नीचे - = y (y कम है, पर और अधिक नीचे बिंदु है)

मुझे एक सिस्टम से दूसरे सिस्टम में अनुवाद करने का एक आसान तरीका चाहिए और इसके विपरीत। ऐसा करने के लिए, (मुझे लगता है) मुझे कुछ ज्ञान की आवश्यकता है जैसे कार्टेसियन निर्देशांक में रखा गया है (0, 0) [स्क्रीन निर्देशांक में शीर्ष बाएं कोने]।

हालांकि एक समस्या है कि स्क्रीन पर इसे अनुवाद करने के बाद कार्टेसियन निर्देशांक में किसी बिंदु के लिए, स्क्रीन निर्देशांक में स्थिति शून्य हो सकती है, जो एक बकवास है। मैं (-इनिटी, + अनंतता) कार्टेशियन कॉर्ड में स्क्रीन निर्देशांक के शीर्ष बाएं कोने को नहीं डाल सकता ...

मैं इसे कैसे हल कर सकता हूं? एकमात्र समाधान मैं सोच सकता हूं कि कार्टेशियन (0, 0) में स्क्रीन (0, 0) डालें और केवल चतुर्भुज प्रणाली की चौथी तिमाही का उपयोग करें, लेकिन उस मामले में कार्टेसियन सिस्टम का उपयोग व्यर्थ है ...

I ' मुझे यकीन है कि स्क्रीन समन्वयकों को कार्टेशियन निर्देशांक में अनुवाद करने के तरीके हैं और इसके विपरीत, लेकिन मैं कम से कम मूल्यों के साथ अपनी सोच में कुछ गलत कर रहा हूं।

+0

स्क्रीन समन्वय ** ** कार्टेशियन है? यह गैर-कार्टशियन बन गया? – thang

+0

वह नकारात्मक निर्देशांक – sgonzalez

+0

@thang चाहता है वाई अक्ष स्क्रीन और कार्टशियन में अलग है। – user1873947

उत्तर

11

बुनियादी एल्गोरिथ्म के लिए कार्तीय निर्देशांक से अनुवाद करने के लिए स्क्रीन निर्देशांक

screenX = cartX + screen_width/2 
screenY = screen_height/2 - cartY 

लेकिन जैसा कि आपने बताया है, कार्टेशियन स्पेस अनंत है, और आपकी स्क्रीन स्पेस नहीं है। स्क्रीन स्पेस और कार्टेशियन अंतरिक्ष के बीच संकल्प को बदलकर इसे आसानी से हल किया जा सकता है। उपरोक्त एल्गोरिदम स्क्रीन स्थान में कार्टेसियन स्पेस = 1 इकाई/पिक्सेल में 1 इकाई बनाता है। यदि आप अन्य अनुपात की अनुमति देते हैं, तो आप आवश्यक सभी कार्टशियन स्थान को कवर करने के लिए या अपनी स्क्रीन स्पेस में "ज़ूम" कर सकते हैं।

यह आपके सभी कार्तीय निर्देशांक जब तक आपके ज़ूम कारक को संशोधित करने के लिए स्क्रीन पर फिट होगा द्वारा करने के लिए

screenX = zoom_factor*cartX + screen_width/2 
screenY = screen_height/2 - zoom_factor*cartY 

अब आप नकारात्मक (या बहुत ज्यादा बड़े) संभाल screenX और Screeny उपरोक्त एल्गोरिथ्म बदल जाएगा।

आप समन्वय अंतरिक्ष की पैनिंग के लिए भी अनुमति दे सकते हैं, जिसका अर्थ है, कार्टेशियन अंतरिक्ष के केंद्र को स्क्रीन के ऑफ-सेंटर होने की अनुमति देता है। यह आपके zoom_factor को यथासंभव तंग रहने की अनुमति देने में भी मदद कर सकता है लेकिन डेटा को भी फिट कर सकता है जिसे कार्टेशियन स्पेस की उत्पत्ति के आसपास समान रूप से वितरित नहीं किया जाता है।

यह करने के लिए

screenX = zoom_factor*cartX + screen_width/2 + offsetX 
screenY = screen_height/2 - zoom_factor*cartY + offsetY 
1

आपको स्क्रीन की चौड़ाई और ऊंचाई जानने की आवश्यकता है।

तो फिर तुम कर सकते हैं:

cartX = screenX - (width/2); 
cartY = -(screenY - (height/2)); 

और:

screenX = cartX + (width/2); 
screenY = -cartY + (height/2); 
+0

दोस्त, तुम इतनी मैला क्यों हो? एक्स और वाई दोनों के लिए चौड़ाई क्यों है? – thang

2

आप स्क्रीन के आकार पता होना चाहिए क्रम में

कन्वर्ट करने के लिए कार्तीय में कनवर्ट सक्षम होने के लिए:

cartesianx = screenx - screenwidth/2; 
cartesiany = -screeny + screenheight/2; 

स्क्रीन में परिवर्तित करें:

screenx = cartesianx + screenwidth/2; 
screeny = -cartesiany + screenheight/2; 

मामलों में आप किसी नकारात्मक स्क्रीन मूल्य के लिए: मैं इस बारे में चिंता नहीं करता, इस सामग्री बस काटा गया कर दिया जाएगा ताकि उपयोगकर्ता को नहीं देखेंगे। यदि यह एक समस्या है, तो मैं कुछ बाधाओं को जोड़ूंगा जो कार्टेसियन समन्वय को बहुत बड़े होने से रोकते हैं।एक और समाधान, चूंकि आपके पास किनारों को +/- अनंत नहीं हो सकता है, इसलिए आपके निर्देशांक को स्केल करना होगा (उदा। 1 पिक्सेल = 10 कार्टेशियन) चलिए इसे scalefactor पर कॉल करें। समीकरण अब कर रहे हैं: पैमाने कारक के साथ कार्तीय को

कनवर्ट करते हैं:

screenx = (cartesianx + screenwidth/2)/scalefactor; 
screeny = (-cartesiany + screenheight/2)/scalefactor; 
1

आप समस्या यह है कि परिणाम से दूर हो सकता है हमेशा होगा:

cartesianx = scalefactor*screenx - screenwidth/2; 
cartesiany = -scalefactor*screeny + screenheight/2; 

Convert पैमाने कारक के साथ स्क्रीन स्क्रीन - या तो ऋणात्मक मान के रूप में, या उपलब्ध स्क्रीन आकार से बड़े मान के रूप में।

कभी-कभी इससे कोई फर्क नहीं पड़ता: उदाहरण के लिए, यदि आपका ग्राफ़िकल एपीआई नकारात्मक मान स्वीकार करता है और आपके लिए आपके ड्राइंग को क्लिप करता है। कभी-कभी इससे कोई फर्क पड़ता है, और उन मामलों के लिए आपके पास एक ऐसा फ़ंक्शन होना चाहिए जो जांचता है कि स्क्रीन पर स्क्रीन निर्देशांक का एक सेट है या नहीं।

आप अपने स्वयं के क्लिपिंग फ़ंक्शंस भी लिख सकते हैं जो स्क्रीन से गिरने वाले निर्देशांक के साथ कुछ उचित करने की कोशिश करते हैं (जैसे नकारात्मक स्क्रीन निर्देशांक को 0 पर टंकण करना, और समन्वय जो अधिकतम ऑनस्क्रीन समन्वय के लिए बहुत बड़े हैं)। हालांकि, ध्यान रखें कि "उचित" आप जो करने की कोशिश कर रहे हैं उस पर निर्भर करता है, इसलिए जब तक आपको वास्तव में उनकी आवश्यकता न हो, ऐसे कार्यों को परिभाषित करने के लिए सबसे अच्छा हो सकता है।


किसी भी मामले में, के रूप में अन्य उत्तर उल्लेख किया है, आप के रूप में समन्वय प्रणालियों के बीच परिवर्तित कर सकते हैं:

cart.x = screen.x - width/2; 
cart.y = height/2 - screen.y; 

और

screen.x = cart.x + width/2; 
screen.y = height/2 - cart.y; 
0

मैं कुछ बढ़ावा C++ आप के लिए माइक्रोसॉफ्ट लेख पर आधारित है, एल्गोरिथ्म बदल जाएगा: https://msdn.microsoft.com/en-us/library/jj635757(v=vs.85).aspx

तुम सिर्फ दो स्क्रीन अंक और में दो अंक जानने की जरूरत आपका समन्वय प्रणाली।फिर आप एक सिस्टम से दूसरे सिस्टम में बिंदु बदल सकते हैं।

#include <boost/numeric/ublas/vector.hpp> 
#include <boost/numeric/ublas/vector_proxy.hpp> 
#include <boost/numeric/ublas/matrix.hpp> 
#include <boost/numeric/ublas/triangular.hpp> 
#include <boost/numeric/ublas/lu.hpp> 
#include <boost/numeric/ublas/io.hpp> 

/* Matrix inversion routine. 
Uses lu_factorize and lu_substitute in uBLAS to invert a matrix */ 
template<class T> 
bool InvertMatrix(const boost::numeric::ublas::matrix<T>& input, boost::numeric::ublas::matrix<T>& inverse) 
{ 
    typedef boost::numeric::ublas::permutation_matrix<std::size_t> pmatrix; 

    // create a working copy of the input 
    boost::numeric::ublas::matrix<T> A(input); 

    // create a permutation matrix for the LU-factorization 
    pmatrix pm(A.size1()); 

    // perform LU-factorization 
    int res = lu_factorize(A, pm); 
    if (res != 0) 
     return false; 

    // create identity matrix of "inverse" 
    inverse.assign(boost::numeric::ublas::identity_matrix<T> (A.size1())); 

    // backsubstitute to get the inverse 
    lu_substitute(A, pm, inverse); 

    return true; 
} 

PointF ConvertCoordinates(PointF pt_in, 
    PointF pt1, PointF pt2, PointF pt1_, PointF pt2_) 
{ 

    float matrix1[]={ 
     pt1.X,   pt1.Y,   1.0f,   0.0f, 
     -pt1.Y,   pt1.X,   0.0f,   1.0f, 
     pt2.X,   pt2.Y,   1.0f,   0.0f, 
     -pt2.Y,   pt2.X,   0.0f,   1.0f 
    }; 

    boost::numeric::ublas::matrix<float> M(4, 4); 
    CopyMemory(&M.data()[0], matrix1, sizeof(matrix1)); 

    boost::numeric::ublas::matrix<float> M_1(4, 4); 
    InvertMatrix<float>(M, M_1); 

    double vector[] = { 
     pt1_.X, 
     pt1_.Y, 
     pt2_.X, 
     pt2_.Y 
    }; 

    boost::numeric::ublas::vector<float> u(4); 
    boost::numeric::ublas::vector<float> u1(4); 
    u(0) = pt1_.X; 
    u(1) = pt1_.Y; 
    u(2) = pt2_.X; 
    u(3) = pt2_.Y; 

    u1 = boost::numeric::ublas::prod(M_1, u); 

    PointF pt; 
    pt.X = u1(0)*pt_in.X + u1(1)*pt_in.Y + u1(2); 
    pt.Y = u1(1)*pt_in.X - u1(0)*pt_in.Y + u1(3); 
    return pt; 
}