2011-04-06 22 views
7

Çok sayıda vektör matematik işi yapıyorum ve bunun için kendi şablonumu yazdım.C++ Vektör Matematik ve OpenGL uyumlu

Gereksinimlerim vektör matematiği (toplama, çıkarma, ölçek, çapraz prod ve nokta prod) çok fazladır, ayrıca benim vektörü float [] olarak geçirebilmem gerekir, böylece openGL bunu kullanabilir.

Bir süredir bunu oldukça mutlu bir şekilde kullanıyorum, bugün bir öğretim görevlisi onu gördü ve inledi. Özellikle nefret ettiği iki şey vardı (bunlardan birini anladım), kalıtımımı kullanmam çünkü is a stilini izlemiyordu. Ve benim dökümüm (T*)this, elbette çözüm yolunda fazla bir şey yoktu.

İlk

: kalıtım, ben böyle benim vektörleri tasarlanmış böylece vec4 giden tarihiyle vec2 yararlanmak gerekiyor.

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() ... 
} 

Bu neden kötü? ve tbh bunu nasıl geliştireceğimi göremiyorum. Ben tür tanımlamak ve bir çeşit getters ve setters sahip olmak için (istiyorum) ihtiyacım var. Ben

template<typename T, int _size> 
VectorT 

gibi yeniden düzenlenmiş ise benim .getX(), .setX() şeyler gevşek ve .at() veya [] gibi bir şey ile değiştirmek gerekir. tbh Kullanıcı tanımalarını daha kolay hale getirmesine rağmen .getX()'un okunabilirliğini tercih ederim.

İkincisi: Bunun neden kötü olduğunu görebilirsiniz, ama o yüzden ben uyarısı operatöre

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

olarak aşırı olduğunuz bir şamandıra dizi bekliyoruz OpenGL yöntemi içine bu vektörler geçebilir hale getirmek için Anladığım kadarıyla, derleyicinin, sınıfın başında üye değişkenleri x, y, z, w koyacağına dair bir garanti yoktur ve dikkatli olmasaydım, bunun yerine v-tablosunu geçebilirim. Ancak itiraf etmeliyim ki şimdiye kadar hiç sorunum olmadı.

Bunun etrafında görebilmemin tek yolu, döndürülecek bir diziyi sürdürmektir. İlk başta vektörlerle uğraşma şeklini değiştirirsem daha kolay olurdu.

+0

Mesaj daha koddur. Operatör * nerede tanımlanır? GetX() ve setX() yöntemleri nerede? –

cevap

6

Bunun yerine GLM kullanmayı düşünebilirsiniz. OpenGL ile entegrasyon da dahil olmak üzere anlattığınız her şeyi (eksik belgelerini buldum) buldum.

+0

Belgeleri eksik neden buldunuz? Katılıyorum: arama fonksiyonu yok ve hangi isim alanında olduğunu tahmin et. – Marnix

+1

@Marnix: Kılavuz (http://glm.g-truc.net/glm-0.9.1.pdf) hakkında yeterli bilgi yok tüm özellikleri, sadece temel olanları nasıl kullanacağınız (örneğin, vektörlerin veya matrislerin şablonlanmış sürümlerini kullanmanın sözünden bahsetmez). API Dokümantasyonu (http://glm.g-truc.net/api-0.9.1/index.html) argümanların işlevini tanımlamak için minimalist bir yaklaşım benimsemiş görünmektedir (ör. Http: //glm.g-truc.net/api-0.9.1/a00237.html#ga48168ff70412019857ceb28b3b2b1f5e?) – andand

+1

Aslında [vmmlib] (http://vmmlib.sourceforge.net/) veya [Eigen] (http: Kişisel olarak GLM üzerinden //eigen.tuxfamily.org/index.php?title=Main_Page). Her ikisi de OpenGL ile kolayca çalışır ve kullanımı kolaydır ve iyi belgelenmiştir. – greyfade

0

Dediğiniz gibi miras kalıtımın "bir" olduğunu suistimal ediyorsunuz. Bu

float dotProduct (vektör2Da, vektör2Db) gibi bir işlev yazdıysanız sorun ortaya çıkabilir;

Bir 2d vektörünün ve bir 3 boyutlu vektörün nokta çarpımı tanımlanmamışsa ve bu aslında tuhaf davranışlara yol açabilecek bir hata olduğunda, bir 3B vektörü geçirebilir ve bir skaler sonuç elde edebilirsiniz. Bu büyük bir anlaşma değil, ama bazı tür kontrolleri atıyorsunuz, ve eğer statik yazımın acısıyla uğraşacaksanız, bu tür hatalar ortaya çıktığında faydalarını da elde edebilirsiniz.

Dizinin bakımı kesinlikle üstün bir çözümdür, tanımlanmamış davranışlara güvenmek istemezsiniz, çünkü sizi ne zaman tamamen vidalayacağınızı asla bilemezsiniz.

+0

Ah 3'ün yerine (veya tam tersi), Vector2D'leri geçerseniz ne olacağını düşünmedim. –

0

muhtemelen böyle bir şey yapmak istiyorum:

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

Sen öğretmenini dinle ve kısmi uzmanlaşma (uyarı: test edilmedi): nasıl kullanabilirim bu konuda

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

Muhtemelen, negatif boyutlu şablon argümanlarına karşı korunmak için boyut türü için size_t (veya imzalı bir int yerine başka bir işaretsiz tamsayı türü) kullanmak isteyebilirsiniz. – 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];} 
} 

Sınıfın bir parçası olmayan bir arkadaşın inner_product yapmasını sağladığınızı unutmayın. türetilmiş türleri!