2011-04-06 16 views
7

मैं बहुत सारे वेक्टर गणित सामग्री कर रहा हूं और इसके लिए अपना स्वयं का टेम्पलेट लिखा है।सी ++ वेक्टर मैथ और ओपनजीएल संगत

मेरी आवश्यकताएं वेक्टर गणित (अतिरिक्त, घटाव, स्केल, क्रॉस प्रोड, और डॉट प्रोड) के बहुत सारे हैं, मुझे भी अपने वेक्टर को फ्लोट के रूप में पास करने में सक्षम होना चाहिए [] ताकि ओपनजीएल इसका उपयोग कर सके।

मैं इसे कभी-कभी खुशी से उपयोग कर रहा हूं, आज एक व्याख्याता ने इसे देखा और चिल्लाया। दो चीजें थीं जिन्हें वह विशेष रूप से नफरत करता था (जिसमें से मैं समझता हूं), मेरा विरासत का उपयोग क्योंकि यह is a शैली का पालन नहीं करता था। और मेरा कास्टिंग (T*)this, निश्चित रूप से उसके पास समाधान के रास्ते में बहुत कुछ नहीं था।

पहले: विरासत, मैं इतना है कि मैं इस तरह मेरे वैक्टर तैयार किया गया vec4 के लिए vec2 का उपयोग करने में सक्षम होने की जरूरत है।

template<typename T> 
Vector2D 
{ 
public: 
getX(), getY(), setX(), setY() .... 
}; 

template<typename T> 
Vector3D : public Vector2D<T> 
{ 
public: 
getZ(), setZ() ... 
} 

template<typename T> 
Vector4D : public Vector3D<T> 
{ 
public: 
getW(), setW() ... 
} 

यह बुरा क्यों है? और tbh मैं नहीं देख सकता कि इसे कैसे सुधारें। मुझे टाइप करना चाहते हैं (चाहते हैं) टाइप को परिभाषित करने में सक्षम होना चाहिए और कुछ प्रकार के गेटर्स और सेटर्स हैं। मैं अपने .getX(), .setX() सामान है और तब तक .at() या [] की तरह कुछ के साथ बदलना होगा अगर मैं यह

template<typename T, int _size> 
VectorT 

की तरह पुन: व्यवस्थित। tbh मैं .getX() की पठनीयता को प्राथमिकता देता हूं, हालांकि यह ऑपरेटर परिभाषाओं को आसान बना देगा।

दूसरा: मैं देख सकता हूँ क्यों यह बुरा है, लेकिन यह तो मैं ओपन की विधि में इन वैक्टर कि एक नाव सरणी मैं सूचक ऑपरेटर

// Defined in Vector2D<T> 
operator*() { return (T*)this; } 

के रूप में अतिभारित किया है उम्मीद पारित कर सकते हैं बनाने के लिए मैं इसे समझता हूं, इस बात की कोई गारंटी नहीं है कि संकलक कक्षा की शुरुआत में सदस्य चर, x, y, z, w को रखेगा, और यदि सावधान नहीं है तो मैं इसके बजाय v-table को पास कर सकता हूं। हालांकि मुझे स्वीकार करना होगा कि अब तक मुझे कोई समस्या नहीं है।

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

+0

पोस्ट अधिक कोड है। 'ऑपरेटर *' कहां परिभाषित किया गया है? GetX() और setX() विधियां कहां हैं? –

उत्तर

6

आप इसके बजाय GLM का उपयोग करने पर विचार करना चाह सकते हैं। ओपनजीएल के साथ एकीकरण सहित यह सब कुछ आपने वर्णन किया है (हालांकि मुझे दस्तावेज की कमी है)।

+0

आपको दस्तावेज़ों की कमी क्यों मिली? मैं इस पर सहमत हूं: कोई खोज फ़ंक्शन और अनुमान नहीं है कि यह किस नामस्थान में है। – Marnix

+1

@Marnix: मैनुअल (http://glm.g-truc.net/glm-0.9.1.pdf) में पर्याप्त जानकारी नहीं है सभी सुविधाओं का उपयोग कैसे करें, केवल मूलभूत (उदाहरण के लिए वेक्टर या मैट्रिस के टेम्पलेट संस्करणों का उपयोग करने का कोई उल्लेख नहीं है)। एपीआई दस्तावेज़ीकरण (http://glm.g-truc.net/api-0.9.1/index.html) ने तर्कों के कार्य का वर्णन करने के लिए एक न्यूनतम दृष्टिकोण लिया है (उदाहरण के लिए http पर 'एम' क्या करता है: //glm.g-truc.net/api-0.9.1/a00237.html#ga48168ff70412019857ceb28b3b2b1f5e?) – andand

+1

मैं वास्तव में [vmmlib] (http://vmmlib.sourceforge.net/) या [Eigen] (http: व्यक्तिगत रूप से जीएलएम पर //eigen.tuxfamily.org/index.php?title=Main_Page)। दोनों ओपनजीएल के साथ आसानी से काम करते हैं, और उपयोग करने में आसान और अच्छी तरह से प्रलेखित हैं। – greyfade

0

जैसा कि आपने कहा था, आप विरासत की "एक-एक" प्रकृति का दुरुपयोग कर रहे हैं। समस्या तब उत्पन्न हो सकती है जब आपने इस

फ्लोट डॉट प्रोडक्ट (वेक्टर 2 डी ए, वेक्टर 2 डी बी) जैसे फ़ंक्शन को लिखा हो;

आप एक 3 डी वेक्टर में पास कर सकते हैं और एक स्केलर परिणाम प्राप्त कर सकते हैं जब वास्तव में 2 डी वेक्टर और 3 डी वेक्टर का डॉट उत्पाद अनिर्धारित होता है और यह वास्तव में एक बग है जो अजीब व्यवहार का कारण बन सकता है। यह माना जाता है कि यह एक बड़ा सौदा नहीं है, लेकिन आप कुछ प्रकार की जांच को फेंक रहे हैं, और यदि आप स्थैतिक टाइपिंग के दर्द से निपटने जा रहे हैं तो आप इसके जैसे बग उत्पन्न होने पर इसके लाभ भी प्राप्त कर सकते हैं।

सरणी को बनाए रखना निश्चित रूप से एक बेहतर समाधान है, आप अपरिभाषित व्यवहार पर भरोसा नहीं करना चाहते हैं, क्योंकि आप कभी नहीं जानते कि यह आपको पूरी तरह से कब खत्म कर रहा है।

+0

आह मैंने नहीं सोचा था कि क्या होगा यदि आप वेक्टर 2 डी की बजाय 3 (या vise versa) के बजाय पास हुए हैं, धन्यवाद। –

0

मैं शायद कुछ इस तरह करते हैं:

template<typename T> 
class VectorT{ 
protected: 
    T* m_data; 
    int m_size; 

public: 
    VectorT(unsigned int size) 
    : m_size(size) 
    { 
    m_data=new T[size]; 
    } 

    virtual ~VectorT() 
    { 
    delete[] m_data; 
    } 

    T* operator*() { return m_data; } 
    T& operator[](int ii) { return m_data[ii]; } 
} 

template<typename T> 
class Vector3 : public VectorT<T> 
{ 
public: 
    Vector3() : VectorT(3) {} 
    T getX() { return m_data[0]; } 
    T getY() { return m_data[1]; } 
    T getZ() { return m_data[2]; } 

    Vector3 crossP(const Vector3& vv) { ... } 
} 
2

आप अपने शिक्षक को सुन सकते हैं, और आंशिक विशेषज्ञता (चेतावनी: परीक्षण नहीं): का उपयोग

template<typename T, int size> 
class Vector; 

template< typename T > 
class Vector< T, 2 > 
{ 
    public : 
    Vector() : data() {} 

    T GetX() const { return data[0]; }; 
    T GetY() const { return data[1]; }; 

    void SetX(const T v) const { data[0]=v; }; 
    void SetY(const T v) const { data[1]=v; }; 

    private : 
    T data[2]; 
}; 

template< typename T > 
class Vector< T, 3 > 
{ 
    public : 
    Vector() : data() {} 

    T GetX() const { return data[0]; }; 
    T GetY() const { return data[1]; }; 
    T GetZ() const { return data[2]; }; 

    void SetX(const T v) const { data[0]=v; }; 
    void SetY(const T v) const { data[1]=v; }; 
    void SetZ(const T v) const { data[2]=v; }; 

    private : 
    T data[3]; 
}; 
+1

शायद नकारात्मक आकार टेम्पलेट तर्कों के खिलाफ सुरक्षा के लिए आकार प्रकार के लिए size_t (या हस्ताक्षरित int के बजाय कुछ अन्य हस्ताक्षरित पूर्णांक प्रकार) का उपयोग करना चाहते हैं। – andand

1

कैसे इस बारे में:

template<class T, int _dim> 
class Vector 
{ 
    T v[_dim]; 
    operator*(){return v;} 

friend T inner_product(Vector<T, _dim> const &v1, Vector<T, _dim> const &v2); 
}; 

template<class T, int _dim> 
T inner_product(Vector<T, _dim> const &v1, Vector<T, _dim> const &v2) 
{ 
    T p = 0.; 
    for(int i; i < _dim; i++) 
     p += v1.v[i] * v2.v[i]; 
    return p; 
} 

template<class T> 
class Vector2 : Vector<T, 2> 
{ 
    float getX() const {return v[0];} 
    float getS() const {return v[0];} 

    float getY() const {return v[1];} 
    float getT() const {return v[1];} 
} 

template<class T> 
class Vector3 : Vector<T, 3>, Vector2<T> 
{ 
    float getZ() const {return v[2];} 
    float getR() const {return v[2];} 
} 

template<class T> 
class Vector4 : Vector<T, 4>, Vector3<T> 
{ 
    float getW() const {return v[3];} 
    float getQ() const {return v[3];} 
} 

ध्यान दें कि inner_product एक दोस्त बनने के लिए, क्लास का हिस्सा नहीं होने के कारण, आप इसे एक प्रकार व्युत्पन्न हो जाएगा!

-1

यहाँ ग के लिए स्टाइल मठ पुस्तकालय (खुला स्रोत) एक पूरा ओपन ++

http://glm.g-truc.net/

संबंधित मुद्दे