• Bağış
  • Splines (Şeritler)

    Yazan : Selim Aksu

    1.Spline

    Çizim terminolojisinde Spline, noktalar kümesi tarafından belirlenen düzgün bir eğri oluşturmak için kullanılan esnek bir şerittir. Şerit boyunca dağıtılmış birçok küçük ağırlıklar, çizim masasında sabit konumda duran bir eğri oluşmasını sağlarlar.
    Spline’lar genelde endüstriyel tasarımda kullanılır. (otomobil, gemi, uçak, uzay aracı gövdeleri, ürün tasarımı gibi.)

    1.1 Spline Eğrileri

    Spline eğrileri de temelde bu yolla oluşturulur.Matematiksel olarak bu tür bir eğri, ilk ve ikinci türevleri, farklı eğri bölümlerinde sürekli olan kübik polinom fonksiyonu ile tanımlanır.Bilgisayar grafiklerinde Spline eğrileri, parçaların sınırlarında süreklilik şartlarını sağlayan polinom kısımları tarafından biçimlendirilen bileşik eğrilerdir.

    1.2 Kontrol Noktaları

    Spline eğrileri, kontrol noktası adı verilen koordinat konum kümeleri verilerek tanımlanırlar. Kontrol noktaları, eğrinin genel şeklini belirler ve sürekli parametrik polinom fonksiyon parçalarında kullanılır. Bunun iki yolu vardır.

    1.3 Spline Gösterimlerinin Sınıflandırılması

    1. Aradeğerleme (Interpolation) Spline’ları

    Eğri tüm kontrol noktalarından geçer.

    1. Yaklaşım (Approximation) Spline’ları

    Eğrinin tüm kontrol noktalarından geçme şartı yoktur


    1.4 Spline Eğri ve Yüzeylerinin Önemi

    2.Bezier Splines

    n+1 adet Pikontrol noktası tarafından kontrol edilen B(t) eğrisi aşağıdaki genel Beziereğri formu ile verilmiştir;


    Burada

    n. derece Bernstein polinomlarıolarak adlandırılır.

    Not: (t0= 1 and (1 ‐t)0= 1)


    : binom katsayıdır (2 terimli)

    Polinomunderecesi, kullanılan kontrol noktalarının sayısından bir azdır.

    2.1 Linear Bezier Spline

    Doğrusal bir Béziereğrisinin t=[0,1] arası formu doğrusal interpolasyon formuna dönüşür.


    P(t) = (1-t)P0 + tP1 ,     0 ≤ t ≤ 1

    2.2 Quadratic Bezier Spline

    Eğri P0,P1& P2 noktalarından geçer.

    2.3 Cubic Bezier Spline

    Eğri P0,P1, P2& P3 noktalarından geçer.

    Kubikform için;

    2.4 Yüksek Derece Eğriler

    Dördüncü Derece Bezier Eğrisi

    Eğri P0,P1, P2, P3 & P4 noktalarından geçer.

    Dördüncü derece form için;



    2.5 Polinom Formu



    2.6 Bezier Eğrileri Dezavantajları

    2.7 Bezier Yüzeyleri

    Üç boyutlu Beziér yüzeylerinin (diğer adıyla Beziér yamalarının) tanımlanması için Beziér eğrilerinin gösteriminin genelleştirilmesi mümkündür. Matematiksel olarak, üç boyutlu yüzeyler iki eğrinin kartezyen çarpımından elde edilebilir. Dolayısıyla, (m+1)(n+1) kontrol noktası tarafından belirtilen Beziér yüzeyinin gösterimi şöyle olacaktır:



    16 kontrol noktası ile tanımlanmış bir Beziér yüzeyi


    16 kontrol noktasıyla tanımlanmış üç boyutlu Beziér yüzeyi

    3. B-Spline Eğrileri

    Verilen n+1 sayıda kontrol noktası;Pitarafından tanımlanan BSplineeğri tanımı:
    

    Burada Ni,k(u) Cox ve de Boor tarafından 1972′de önerilen BSplinefonksiyonlarıdır.

    k parametresi BSplineeğrinin derecesini (k1) kontrol eder ve genellikle kontrol noktası sayısından bağımsızdır.

    Ui parametrik düğüm (knots) ya da düğüm değerleri olarak adlandırılır. Açık bir eğri için şu formda verilmiştir:




    (k1) derecesinde eğriyi (n+1) sayıda kontrol noktası ile tanımlamak için (n+k+1) sayıda düğüm (knots) gereklidir.


    Bu eşitlik gösterirki;

    Doğrusal eğri için en az 2

    2.derece eğri için en az3

    Kubik eğri için ise en az 4 kontrol noktası gerekir.

    Aşağıdaki şekiller BSplinefonksiyonlarının şekillerini göstermektedir:

    Doğrusal fonksiyon

    k=2

    2.derecefonksiyon

    k=3

    kubikfonksiyon

    k=4

    3.1 BSpline Eğrileri Özellikleri

    Kontrol noktası sayısı polinomunderecesinden bağımsızdır.


    Sarı noktalar: verteks

    Sol üst ok: Doğrusal k=2

    Sağ üst ok: 2.derece B-spline k=3

    Sağ orta ok: Kubik B-spline k=4

    Sağ alt ok: 4.derece B-spline k=5


    3.2 Bezier/BSpline Eğrileri

    BezierHarmanlama Fonksiyonları (BezierBlendingFunctions); Bi,n


    BsplineHarmanlama Fonksiyonları (BsplineBlendingFunctions); Ni,k



    Sağ alt okla gösterilen nokta hariç diğer 3 belirtilen nokta hareket ettiriliyor.

    3.3 Uniform BSpline Eğrileri

    Bsplineuniformolduğu zaman n dereceli Bsplinefonksiyonlarıbirbirinin kaydırılmış kopyasıdırlar. Eğri boyunca, düğümler (knots) eşit mesafelerde yerleşmiştir.

    4. Rasyonel Eğriler ve NURBS(Rational Curves and NURBS)

    4.1 Rasyonel Bezier Eğrileri

    Rasyonel Bézier formunda, rastgele şekiller elde edilebilmesi için kontrol noktalarına ayarlanabilir ağırlıklar eklenmiştir.

    n + 1 kontrol noktası; Pi için rasyonel Bézier eğrisi:


    Pay kısmında yeralanterim ağırlıklı BernsteinşeklindeBéziereğrisidir ve paydada ise Bernsteinpolinomlarınınağırlıklı toplamları yer almaktadır.
    Daha basitçe;


    formunda ifade edilebilir.

    4.2 Rasyonel BSpline Eğrileri

    Bir rasyonel eğri 2 polinomun birbirine oranı olarak tanımlanmıştır.Rasyonel eğride kontrol noktaları homojen koordinatlarda tanımlanmıştır.


    dolayısıyla rasyonel BSpline eğrisi:


    formunda ifade edilebilir.

    Ri,k(u) rasyonel BSpline taban fonksiyonlarıdır.


    Yukarıdaki eşitlik gösterir ki;Ri,k(u) rasyonel olmayan taban fonksiyonları;

    Ni,k(u)’nıngenelleştirilmiş halidir.

    Ri,k(u) eşitliğine hi=1 yerleştirilmesi durumunda rasyonel olmayan formla

    yaklaşık aynı özellikleri gösterir.

    4.3 NURBS


    NURBS eğrisinin genel formu;


    k: kontrol noktası (Pi) sayısı

    wi: ağırlıklar (weigths)

    Payda normalleme faktörüdür (normalizingfactor).

    NURBS genel formu aşağıdaki gibi ifade edilebilir:





    Rinfonksiyonları, rasyonel taban fonksiyonları (rational basis functions) olarak adlandırılır.

    4.4 NURBS Örnekleri


    Uniform düğüm (knot) vektörü


    Uniformolmayan (nonuniform) düğüm (knot) vektörü

    4.5 NURBS’ün Gelişimi

    4.6 NURBS Avantajları

    5. Catmull-Rom Splines

    Eğri bütün kontrol noktalarından geçmelidir.Bir noktaı hesaplamak için Şekilde görüldüğü gibi o noktanın iki yanınadki noktalar gereklidir.P1,P2,P3,P4 gibi kontrol noktaları ve t değeriyle noktanın yeri şu şekilde hesaplanabilir.

    q(t) = 0.5 *( (2 * P1) +

    (-P0 + P2) * t +
    (2*P
    0 - 5*P1 + 4*P2 - P3) * t2 +
    (-P
    0 + 3*P1- 3*P2 + P3) * t3)

    6. Hermite Splines

    Oluşturmak için her kontrol noktasının tanjant vektörlerini gerektirir.

    P1:Eğrinin başlangıç noktası.

    P2:Eğrinin bitiş noktası

    T1:Eğrinin başlangıç noktasından nasıl çıktığının tanjantu

    T2:Eğrinin bitiş noktasına nasıl vatdığının tanjantı

    Bu 4 vektör ve Hermite Fonksiyonları bir araya getirildiğinde;

    h1(s) = 2s^3 – 3s^2 + 1

    h2(s) = -2s^3 + 3s^2

    h3(s) = s^3 – 2s^2 + s

    h4(s) = s^3 – s^2

    7. Beta-splines:

    Otomatik süreklilik ve tanjant ile kavis uzunluğu üzerinde tam manasıyla kontrol sağlar.

    8. Programlama Örnekleri

    C++( Bu C++ programı ekrana bezier eğrisi çizer.4 nokta var.2′si kontrol noktası)

    #include <GL/glut.h>

    GLfloat ctrlpts[4][3] = {
    {-0.4, 0.4,  0.0},
    {-0.1, 2.0,  0.0},
    { 0.1,-2.0,  0.0},
    { 0.4, 0.4,  0.0}
    };
    void display()
    {
    GLint k;
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0, 0.0, 1.0);
    glBegin(GL_LINE_STRIP);
    for (k= 0; k<= 50; k++)
    glEvalCoord1f((GLfloat) (k)/50.0);
    glEnd();
    glPointSize(5.0);
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_POINTS);
    for (k= 0; k< 4; k++)
    glVertex3fv(&ctrlpts[k][0]);
    glEnd();

    glutSwapBuffers();
    }
    void init()
    {
    glClearColor(1.0,1.0,1.0,0.0);
    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, *ctrlpts);
    glEnable(GL_MAP1_VERTEX_3);
    }
    int main(int argc, char ** argv)
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(400,400);
    glutInitWindowPosition(50, 50);
    glutCreateWindow(“Bezier Eğrisi”);
    init();
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
    }

    1. C++(Mouse ile işaretlenen noktalardan geçen bezier eğrisi çizdirmek.)

    #include “gl/glut.h”

    static int Genislik = 500;
    static int Yukseklik =500;

    GLfloat cpts[4][3];
    int ncpts = 0;

    void Baslat(void)
    {
    glClearColor(1.0,1.0,1.0,0.0);
    glEnable(GL_MAP1_VERTEX_3);
    }

    void Goster(void)
    {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 0.0, 0.0);
    glPointSize(5.0);
    }
    void EgriCiz(){
    glColor3f(0.0, 0.0, 0.0);
    glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &cpts[0][0]);
    glMapGrid1f(30, 0.0, 1.0);
    glEvalMesh1(GL_LINE, 0, 30);
    glFlush();

    }

    void FareDinle(GLint button,GLint action,GLint x,GLint y)
    {
    float wx, wy;
    if(button==GLUT_LEFT_BUTTON && action==GLUT_DOWN){
    wx = (2.0 * x) / (float)(Genislik – 1) – 1.0;
    wy = (2.0 * (Yukseklik – 1 – y)) / (float)(Yukseklik – 1) – 1.0;
    if (ncpts ==4)
    return;
    cpts[ncpts][0] = wx;
    cpts[ncpts][1] = wy;
    cpts[ncpts][2] = 0.0;
    ncpts++;
    glBegin(GL_POINTS);
    glVertex3f(wx, wy, 0.0);
    glEnd();
    glFlush();
    }
    else
    if(button==GLUT_RIGHT_BUTTON)
    EgriCiz();
    }

    void main(int argc, char** argv)
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(Genislik,Yukseklik);
    glutInitWindowPosition(100, 150);
    glutCreateWindow(“İnteraktif Eğri Çiz”);
    glutDisplayFunc(Goster);
    glutMouseFunc(FareDinle);
    Baslat();
    glutMainLoop();
    }

    8.3 Java(İnteraktif 2D Bezier splines)

    import java.awt.*;
    
    import java.awt.event.*;
    
    import java.util.StringTokenizer;
    
    public class Bezier extends java.applet.Applet
    
      implements MouseMotionListener{
    
    Image buffImage;          Graphics buffGraphics;
    
    int n = 4, n1,  w,h,h1,w2;
    
    double[] Px,Py;
    
    public void drawFun(){
    
      double step = 1./w2, t = step;
    
      double[] B = new double[n1], Bo = new double[n1], Bold = new double[n1];
    
      B[1] = Bo[1] = h1;
    
      Color[] iColor = {Color.gray, Color.red, new Color(0f,.7f,0f),
    
       Color.blue, Color.magenta, new Color(0f,.8f,.8f), new Color(.9f,.9f,0f) };
    
      for (int k = 1; k < w2; k++){
    
       System.arraycopy(B,1,Bold,1,n);
    
       System.arraycopy(Bo,1,B,1,n);
    
       for (int j = 1; j < n; j++)        //  basis functions calculation
    
        for (int i = j+1; i > 0; i--)
    
         B[i] = (1-t)*B[i] + t*B[i-1];
    
       for (int m = 1; m <= n; m++){
    
        buffGraphics.setColor(iColor[m % 7]);
    
        buffGraphics.drawLine(w2+k-1, h1-(int)Bold[m], w2+k, h1-(int)B[m] );}
    
       t += step;
    
      }
    
    }
    
    public void drawSpline(){
    
      double step = 1./w2, t = step;
    
      double[] Pxi = new double[n], Pyi = new double[n];
    
      int X,Y, Xold = (int)Px[0], Yold = h1-(int)Py[0];
    
      buffGraphics.clearRect(0,0, w2, h);
    
      buffGraphics.setColor(Color.blue);
    
      for (int i = 0; i < n; i++){
    
       X = (int)Px[i];  Y = h1-(int)Py[i];
    
       buffGraphics.drawRect(X-1,Y-1, 3,3);}
    
      if ( n > 2 ){
    
       int Xo = Xold, Yo = Yold;
    
       for (int i = 1; i < n; i++){
    
        X = (int)Px[i];  Y = h1-(int)Py[i];
    
        buffGraphics.drawLine(Xo,Yo, X,Y);
    
        Xo = X;  Yo = Y;}
    
      }
    
      buffGraphics.setColor(Color.red);
    
      for (int k = 1; k < w2; k++){
    
       System.arraycopy(Px,0,Pxi,0,n);
    
       System.arraycopy(Py,0,Pyi,0,n);
    
       for (int j = n-1; j > 0; j--)        //  points calculation
    
        for (int i = 0; i < j; i++){
    
         Pxi[i] = (1-t)*Pxi[i] + t*Pxi[i+1];
    
         Pyi[i] = (1-t)*Pyi[i] + t*Pyi[i+1];}
    
       X = (int)Pxi[0];  Y = h1-(int)Pyi[0];
    
       buffGraphics.drawLine(Xold,Yold, X,Y );
    
       Xold = X; Yold = Y;
    
       t += step;
    
      }
    
    }
    
    public void init() {
    
      w = Integer.parseInt(getParameter("width"));
    
      h = Integer.parseInt(getParameter("height"));  h1 = h-1; w2 = w/2;
    
      String s = getParameter("N"); if (s != null) n = Integer.parseInt(s);
    
      n1 = n+1;
    
      Px = new double[n];  Py = new double[n];
    
      s=getParameter("pts");
    
      if (s != null){
    
       StringTokenizer st = new StringTokenizer(s);
    
       for (int i = 0; i < n; i++){
    
        Px[i] = w2*Double.valueOf(st.nextToken()).doubleValue();
    
        Py[i] = h1*Double.valueOf(st.nextToken()).doubleValue();}}
    
      else{
    
       Px[0] = .1*w2; Px[1] = .1*w2; Px[2] = .9*w2; Px[3] = .9*w2;
    
       Py[0] = .1*h1; Py[1] = .9*h1; Py[2] = .9*h1; Py[3] = .1*h1;}
    
      buffImage = createImage(w, h);
    
      buffGraphics = buffImage.getGraphics();
    
      setBackground(Color.white);
    
      buffGraphics.clearRect(0,0, w, h);
    
      addMouseMotionListener(this);
    
      drawFun();
    
      drawSpline();
    
    }
    
    public void destroy(){ removeMouseMotionListener(this); }
    
    public void mouseMoved(MouseEvent e){}  //1.1 event handling
    
    public void mouseDragged(MouseEvent e) {
    
      int x = e.getX();  if (x < 0) x = 0;  if (x > w2-3) x = w2-3;
    
      int y = h1 - e.getY();  if (y < 0) y = 0;  if (y > h1) y = h1;
    
      int iMin = 0;
    
      double Rmin = 1e10, r2,xi,yi;
    
      for (int i = 0; i < n; i++){
    
       xi = (x - Px[i]); yi = (y - Py[i]);
    
       r2 = xi*xi + yi*yi;
    
       if ( r2 < Rmin ){ iMin = i; Rmin = r2;}}
    
      Px[iMin] = x; Py[iMin] = y;
    
      drawSpline();
    
      repaint();
    
    }
    
    public void paint(Graphics g) {
    
      g.drawImage(buffImage, 0, 0, this);
    
    //  showStatus( " " + x +"  " + y);
    
    }
    
    public void update(Graphics g){ paint(g); }
    
    }
    
    8.4 C++
    						
    						

    
    				

    GLfloat ctrlpoints[4][4][3] = {

    {{-1.5, -1.5, 4.0}, {-0.5, -1.5, 2.0},

    {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}},

    {{-1.5, -0.5, 1.0}, {-0.5, -0.5, 3.0},

    {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}},

    {{-1.5, 0.5, 4.0}, {-0.5, 0.5, 0.0},

    {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}},

    {{-1.5, 1.5, -2.0}, {-0.5, 1.5, -2.0},

    {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}}

    };

    void display(void)

    {

    int i, j;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glPushMatrix ();

    glRotatef(15.0, 1.0, 1.0, 1.0);

    for (j = 0; j <= maxJ; j++) {

    glColor3f(1.0, 0.0, 0.0);

    glBegin(GL_LINE_STRIP);

    for (i = 0; i <= 30; i++)

    glEvalCoord2f((GLfloat)i/30.0, (GLfloat)j/8.0);

    glEnd();

    glColor3f(0.0, 0.0, 1.0);

    glBegin(GL_LINE_STRIP);

    for (i = 0; i <= 30; i++)

    glEvalCoord2f((GLfloat)j/8.0, (GLfloat)i/30.0);

    glEnd();

    }

    glPopMatrix ();

    glFlush();

    }

    void init(void)

    {

    glClearColor (0.0, 0.0, 0.0, 0.0);

    glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,

    0, 1, 12, 4, &ctrlpoints[0][0][0]);

    glEnable(GL_MAP2_VERTEX_3);

    glEnable(GL_DEPTH_TEST);

    glShadeModel(GL_FLAT);

    }


    Benzer Yazılar:

    Bilgisayar Kavramları üzerinde şu anda okumakta olduğunuz 'Splines (Şeritler)' isimli yazı 10 Aug 2009 tarihinde, saat: 17:00 'de Şadi Evren ŞEKER tarafından gönderilmiş, toplam 1300 defa okunmuştur.

    Benzer yazıları Bilgisayar Grafiği (Computer Graphics) kategorilerinden okuyabilirsiniz. Yazar ile irtibat kurmak için email gönderebilirsiniz. Yazıya yorum yapabilir ya da yapılan yorumları RSS 2.0 ile takibe alabilirsiniz.


    Category: Bilgisayar Grafiği (Computer Graphics)
    1 response to “Splines (Şeritler)”
    1. Harun KILIÇ says:

      Teşeküürler, çok güzel bir çalışma.
      Hisse senedi verilerinden grafikler çizdireceğim. Araştırma yaparken bu sayfaya ulaştım.

    Leave a Reply