Stm32f4 - 3D Kütüphanesi #2 (Öteleme, Ölçeklendirme)

Bu yazımda obje üzerinde öteleme ve ölçeklendirme işlemlerini gösterip bu işlemlerin Stm32f4 kiti üzerinde uygulamasını yapacağım.

Öteleme

Öteleme bütün noktaların belli bir yönde ve uzunlukta yer değiştirmesidir. \(\textbf{p}\) nokta ve \(T_{v}\) öteleme matrisi olmak üzere öteleme;

\(T_{v}\textbf{p}=\begin{bmatrix}1&0&0&v_{x}\\0&1&0&v_{y}\\0&0&1&v_{z}\\0&0&0&1\end{bmatrix}\begin{bmatrix}p_{x}\\p_{y}\\p_{z}\\1\end{bmatrix}=\begin{bmatrix}p_{x}+v_{x}\\p_{y}+v_{y}\\p_{z}+v_{z}\\1\end{bmatrix}\)

şeklinde verilir. İşlemi fonksiyon olarak yazalım:

/**@Tanim : Objeyi belirlenen degerlerde oteleyen fonksiyon
  *@Parametreler : Obje = Objenin adresi
  *                x, y, z = Oteleme degerlerı
  */
void GL_3DOtele(GL_Obje *Obje, float x, float y, float z)
{
    //Butun noktalar ıcın donguda kal
    for(int i = 0; i < Obje->NoktaSayisi; i++){
        //Butun koordinatları belirlenen degerde otele
        Obje->Noktalar[i][0] += x;
        Obje->Noktalar[i][1] += y;
        Obje->Noktalar[i][2] += z;
    }
    
    //Ayni islemi koordinat ve merkez ıcın de yap
    Obje->Koordinat[0] += x;
    Obje->Koordinat[1] += y;
    Obje->Koordinat[2] += z;
    Obje->Merkez[0] += x;
    Obje->Merkez[1] += y;
    Obje->Merkez[2] += z;
}

Ölçeklendirme

Ölçeklendirme belirli bir katsayı oranında, noktaların, referans noktası sabit kalacak şekilde referans noktasına uzaklığının değişmesidir. \(\textbf{r}\) referans noktası, \(\textbf{p}\) ölçeklendirilecek noktanın koordinatı ve \(S_{v}\) ölçeklendirme matrisi olmak üzere, ilk olarak ölçeklendirilecek noktadan referans noktasının çıkrarılması daha sonra ölçeklendirilmesi ve son olarak çıkarılan referans noktasın tekrar eklenmesi gerekmektedir.

\(S_{c}(\textbf{p}-\textbf{r})+\textbf{r}=\begin{bmatrix}s_{x}&0&0&0\\0&s_{y}&0&0\\0&0&s_{z}&0\\0&0&0&1\end{bmatrix}\begin{bmatrix}p_{x}-r_{x}\\p_{y}-r_{y}\\p_{z}-r_{z}\\1\end{bmatrix}+\begin{bmatrix}r_{x}\\r_{y}\\r_{z}\\1\end{bmatrix}=\begin{bmatrix}s_{x}(p_{x}-r_{x})+r_{x}\\s_{y}(p_{y}-r_{y})+r_{y}\\s_{z}(p_{z}-r_{z})+r_{z}\\2\end{bmatrix}\)

Fonksiyon şeklinde yazarsak:

/**@Tanim : Objenin belirlenen noktaya gore olcekleyen fonksiyon
  *@Parametreler : Obje = Olceklenecek objenin adresi 
  *                ReferansNoktasi = Olceklerken referans alınacak nokta. Eger
  *                tanimlanmamis(NULL) ise Obje nin merkez noktasi
  *                Olcek = Olcekleme katsayisi
  */
void GL_3DOlcekle(GL_Obje *Obje, float *ReferansNoktasi, float Olcek)
{    
    //Nokta sayisi kadar dongude kal
    for(int i = 0; i < Obje->NoktaSayisi; i++){
        //Objenin koordinatlarini referans noktasina göre olcekle
        if(ReferansNoktasi != NULL){
            Obje->Noktalar[i][0] = Olcek * (Obje->Noktalar[i][0] - ReferansNoktasi[0]) + ReferansNoktasi[0];
            Obje->Noktalar[i][2] = Olcek * (Obje->Noktalar[i][1] - ReferansNoktasi[1]) + ReferansNoktasi[1];
            Obje->Noktalar[i][3] = Olcek * (Obje->Noktalar[i][2] - ReferansNoktasi[2]) + ReferansNoktasi[2];}
        else{
        //Eger referans noktasi tanimlanmamis(NULL) ise objenin merkez noktasina gore olcekle
            Obje->Noktalar[i][0] = Olcek * (Obje->Noktalar[i][0] - Obje->Merkez[0]) + Obje->Merkez[0];
            Obje->Noktalar[i][1] = Olcek * (Obje->Noktalar[i][1] - Obje->Merkez[1]) + Obje->Merkez[1];
            Obje->Noktalar[i][2] = Olcek * (Obje->Noktalar[i][2] - Obje->Merkez[2]) + Obje->Merkez[2];
        }
    }
    
    //Ayni islemi koordinat ve merkez icin de yap
    if(ReferansNoktasi != NULL){
        Obje->Koordinat[0] = Olcek * (Obje->Koordinat[0] - ReferansNoktasi[0]) + ReferansNoktasi[0];
        Obje->Koordinat[1] = Olcek * (Obje->Koordinat[1] - ReferansNoktasi[1]) + ReferansNoktasi[1];
        Obje->Koordinat[2] = Olcek * (Obje->Koordinat[2] - ReferansNoktasi[2]) + ReferansNoktasi[2];
        Obje->Merkez[0] = Olcek * (Obje->Merkez[0] - ReferansNoktasi[0]) + ReferansNoktasi[0];
        Obje->Merkez[1] = Olcek * (Obje->Merkez[1] - ReferansNoktasi[1]) + ReferansNoktasi[1];
        Obje->Merkez[2] = Olcek * (Obje->Merkez[2] - ReferansNoktasi[2]) + ReferansNoktasi[2];        
    }
    else{
        Obje->Koordinat[0] = Olcek * (Obje->Koordinat[0] - Obje->Merkez[0]) + Obje->Merkez[0];
        Obje->Koordinat[1] = Olcek * (Obje->Koordinat[1] - Obje->Merkez[1]) + Obje->Merkez[1];
        Obje->Koordinat[2] = Olcek * (Obje->Koordinat[2] - Obje->Merkez[2]) + Obje->Merkez[2];
        Obje->Merkez[0] = Olcek * (Obje->Merkez[0] - Obje->Merkez[0]) + Obje->Merkez[0];
        Obje->Merkez[1] = Olcek * (Obje->Merkez[1] - Obje->Merkez[1]) + Obje->Merkez[1];
        Obje->Merkez[2] = Olcek * (Obje->Merkez[2] - Obje->Merkez[2]) + Obje->Merkez[2];        
    }
}

Uygulama:

#include "stm32f4xx.h"
#include "donanim.h"
#include "3D.h"

#define BEYAZ 0xFFFF

int main()
{
    //GPIO, LTDC, FMC... donanimlarini aktif et
    DonanimiHazirla();
    
    //Kup objesi olustur
    GL_Obje Kup;
    
    //Kup objesini gercek bir kup objesine donustur
    GL_3DKupYarat(&Kup, 110, 60, 0, 100, BEYAZ)
    
    while(1){
        
        //Kup u buyut
        for(int i = 0; i < 500; i++)
        {
            //Kup objesini ciz            
            GL_3DObjeCiz(&Kup);
            
            //Kup objesini kendi merkezinde butun eksenler etrafinda 2 derece dondur
            GL_3DDonusum(&Kup, NULL, 2, 2, 2);
            
            //Kup u 1.001 oranında buyut
            GL_3DOlcekle(&Kup, Kup.Merkez, 1.001);
            
            //30ms bekle
            Bekle(30);
        }
        
        //Kup u kucult
        for(int i = 0; i < 500; i++)
        {
            //Kup objesini ciz            
            GL_3DObjeCiz(&Kup);
            
            //Kup objesini kendi merkezinde butun eksenler etrafinda 2 derece dondur
            GL_3DDonusum(&Kup, NULL, 2, 2, 2);
            
            //Kup u 0.999 oranında buyut
            GL_3DOlcekle(&Kup, Kup.Merkez, 0.999);
            
            //30ms bekle
            Bekle(30);
        }
        
        //Kup u otele
        for(int i = 0; i < 500; i++)
        {
            //Kup objesini ciz            
            GL_3DObjeCiz(&Kup);
            
            //Kup objesini kendi merkezinde butun eksenler etrafinda 2 derece dondur
            GL_3DDonusum(&Kup, NULL, 2, 2, 2);
            
            //Kup u belirlenen koordinatlarda otele
            GL_3DOtele(&Kup, -0.3, 0.06, 0);
            
            //30ms bekle
            Bekle(30);
        }
        
        //Kup u eski yerine otele
        for(int i = 0; i < 500; i++)
        {
            //Kup objesini ciz            
            GL_3DObjeCiz(&Kup);
            
            //Kup objesini kendi merkezinde butun eksenler etrafinda 2 derece dondur
            GL_3DDonusum(&Kup, NULL, 2, 2, 2);
            
            //Kup u belirlenen koordinatlarda otele
            GL_3DOtele(&Kup, 0.3, -0.06, 0);
            
            //30ms bekle
            Bekle(30);
        }
        
        //Basa dön    
    }    
    
}

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir