^Back To Top

foto1 foto2 foto3 foto4 foto5


Get Adobe Flash player

Là một lĩnh vực của khoa học máy tính – Đồ họa máy tính có sự phát triển nhanh chóng, giúp giao tiếp giữa con người và máy tính trở nên thân thiện. Các chương trình đồ họa ứng dụng rất phong phú và đa dạng trong tất cả các lĩnh vực.

Bài báo này đề cập đến giải thuật vẽ ngôi sao và bông hoa trên cơ sở các giải thuật vẽ hình cơ bản của đồ họa máy tính bằng ngôn ngữ Java.

NỘI DUNG

1. Vẽ ngôi sao 5 cánh

- Ý tưởng:

+ Cách xác định đỉnh: Nhận thấy 1 ngôi sao có 5 đỉnh sẽ cách đều tâm, hai đỉnh kề nhau sẽ cách nhau một góc 72o. Vậy để xác định đỉnh, chúng ta chỉ cần chọn 1 điểm cách tâm 1 khoảng r, sau đó quay quanh tâm theo góc 72o ta sẽ được đỉnh tiếp theo.

+ Từ 5 đỉnh của ngôi sao, sử dụng thuật toán dda nối các điểm thành các đường thẳng tạo thành ngôi sao.

t2 hoai1

- Thuật toán

+ Bước 1: Xác định đỉnh của ngôi sao bằng công thức

x[i] = x *cos(i* 72o) – y *sin(y * 72o) + (y +r)sin(i * 72o) + x(1- cos(i*72o))

y[i] = x *sin(i* 72o) + y *cos(y * 72o) + (y +r)(1-cos(i * 72o)) + x*sin(i*72o)

+ Bước 2: Sử dụng thuật toán DDA nối các điểm: 1 và 3, 1 và 4, 2 và 3, 2 và 5, 3 và 5 Ta được hình sau:

t2hoai2

- Cài đặt

      void ngoisao(Graphics g, intxt, intyt, intr) {

         floatx[] = newfloat[5], y[] = newfloat[5], grad = (float) ((72 * 3.14) / 180);

         x[0] = xt;

         y[0] = yt - r;

         for (inti = 1; i < 5; i++) {

             x[i] = (float) (x[0] * Math.cos(i * grad) - y[0] * Math.sin(i * grad) + yt * Math.sin(i * grad)

                      + xt * (1 - Math.cos(i * grad)));

             y[i] = (float) (x[0] * Math.sin(i * grad) + y[0] * Math.cos(i * grad) + yt * (1 - Math.cos(i * grad))

                      - xt * Math.sin(i * grad));

         }

         DDA(g, Math.round(x[0]), Math.round(y[0]), Math.round(x[2]), Math.round(y[2]));

         DDA(g, Math.round(x[0]), Math.round(y[0]), Math.round(x[3]), Math.round(y[3]));

         DDA(g, Math.round(x[1]), Math.round(y[1]), Math.round(x[3]), Math.round(y[3]));

         DDA(g, Math.round(x[1]), Math.round(y[1]), Math.round(x[4]), Math.round(y[4]));

         DDA(g, Math.round(x[2]), Math.round(y[2]), Math.round(x[4]), Math.round(y[4]));

    }

2. Vẽ bông hoa 5 cánh

- Ý tưởng:

+ Bông hoa sẽ gồm 5 cánh là 5 hình tròn được xếp đều nhau quanh 1 hình tròn tâm

+ Cách xác định tâm của 5 cánh hoa: Tương tự như hình ngôi sao, ta nhận thấy 5 cánh sẽ cách đều tâm, nên sẽ có 5 tâm của mỗi cánh cách đều tâm chính, hai tâm kề nhau sẽ cách nhau một góc 72o. Vậy nên để xác định tâm, chúng ta chỉ cần chọn 1 điểm cách tâm 1 khoảng r (chúng ta có thể nâng khoảng r lên r +r /3 để các cánh hoa xa nhau hơn), sau đó quay quanh tâm theo góc 72o ta sẽ được cái đỉnh tiếp theo.

+ Sử dụng các thuật toán vẽ hình tròn, và tô màu để vẽ.

- Thuật toán:

+ Bước 1: Xác vị trí của cánh theo công thức:

x[i] = x *cos(i* 72o) – y *sin(y * 72o) + y sin(i * 72o) + x(1- cos(i*72o))

y[i] = x *sin(i* 72o) + y *cos(y * 72o) + y (1-cos(i * 72o)) + x*sin(i*72o)

+ Bước 2: Vẽ và tô màu các cánh

t2 hoai4

+ Bước 3: Vẽ và tô màu tâm vào giữa các cánh.

t2 hoai5

- Cài đặt

          void veHoa(Graphics g, intxt, intyt, intr)

{

         floatx[] = newfloat[5], y[] = newfloat[5], grad = (float) ((72 * 3.14) / 180);

         x[0] = xt;

         y[0] = yt - r;

         r += r/3;

         for (inti = 1; i < 5; i++) {

             x[i] = (float) (x[0] * Math.cos(i * grad) - y[0] * Math.sin(i * grad) + yt * Math.sin(i * grad)

                      + xt * (1 - Math.cos(i * grad)));

             y[i] = (float) (x[0] * Math.sin(i * grad) + y[0] * Math.cos(i * grad) + yt * (1 - Math.cos(i * grad))

                      - xt * Math.sin(i * grad));

         }

         g.setColor(new Color(160, 236, 144));

         for (inti = 0; i < 5; i++) {

             g.setColor(new Color(160, 236, 144));

             if (i == 1)

                 totron(g, (int) x[i], (int) y[i], r / 2);

             else

                 totron(g, (int) x[i], (int) y[i], r / 2);

             g.setColor(Color.black);

             dtron(g, (int) x[i], (int) y[i], r / 2);

         }

         g.setColor(new Color(225, 208, 57));

         totron(g, (int) xt, (int) yt, r / 2);

    }

KẾT LUẬN

Trên nền tảng các thuật toán đồ họa cơ sở có thể áp dụng để vẽ các hình phức tạp hơn nhằm xây dựng ứng dụng cụ thể. Đây là một mảng hết sức thú vị và có rất nhiều ứng dụng, đặc biệt trong lĩnh vực giải trí. Với việc dùng các thuật toán vẽ đường thẳng, vẽ đường tròn, tô màu, vẽ ngôi sao, bông hoa tác giả đã xây dựng game Snacke”.

t2 hoai6

Giao diện chính

t2 hoai7

Màn chơi 1

t2 hoai8

Màn chơi 2

t2 hoai 10

Màn chơi 4

t2 hoai 11

Màn chơi 5

t2 hoai 12

Kết thúc

TÀI LIỆU THAM KHẢO

[1]. Francis S. Hill, Computer Graphics, Macmillan Publishing Company, NewYork, 1990

[2]. James D.Foley, Andries Van Dam, Feiner, John Hughes, Computer Graphics - Principle and Practice, Addision Wesley, NewYork, 1996

[3]. Dương Anh Đức, Lê Đình Duy. Giáo trình Đồ họa máy tính, Trường Đại học Khoa học Tự nhiên, 1996

[4]. Lê Tấn Hùng- Huỳnh Quyết Thắng. Kỹ thuật đồ họa, NXB Khoa học và Kỹ thuật, Hà Nội 2004

PHỤ LỤC

- Cài đặt thuật toán DDA:

    void DDA(Graphics g,int x1,int y1,int x2,int y2){

        int dx, dy, step;

        float y_inc, x_inc, x, y;

        dx = x2 - x1;

        dy = y2 - y1;

        if(Math.abs(dx)> Math.abs(dy))

            step = Math.abs(dx);

        else

            step = Math.abs(dy);

        x_inc =(float) dx / step;

        y_inc =(float) dy / step;

        x = x1;

        y = y1;

        putpixel(g,(int) x,(int) y);

        for(int k =1; k <= step; k++){

            x = x + x_inc;

            y = y + y_inc;

            putpixel(g,(int) x,(int) y);

        }

    }

- Cài đặt thuật toán Bresenham vẽ đường tròn

privatevoid put8pixel(int xc,int yc,int x,int y)

{

    putpixel(g, x + xc, y + yc);

    putpixel(g,-x + xc, y + yc);

    putpixel(g, x + xc,-y + yc);

    putpixel(g,-x + xc,-y + yc);

    putpixel(g, y + xc, x + yc);

    putpixel(g,-y + xc, x + yc);

    putpixel(g, y + xc,-x + yc);

    putpixel(g,-y + xc,-x + yc);

}

privatevoid circle(int x0,int y0,int r)

{

  int x =0;

  int y = r;

  int p =3-2* r;

  while(x <= y)

  {

   put8pixel(x0,y0,x,y,15);

   if(p <0)

   {

       p = p +4* x +6;

   }

   else

   {

            p = p +4*(x - y)+10;

            y = y -1;

   }

   x = x +1;

  }

}

 

- Tô hình vuông

+ Mục đích: Tạo chướng ngại vật trong trò chơi

+ Ý tưởng: Sử dụng thuật toán tô màu scanline để tô màu

+ Code:

     void toVuong(Graphics g,intx, inty,intr){

          for(inti=0;i<=r;i++){

              DDA(g,x,y+i,x+r,y+i);

          }

}

- Tô hình tròn

+ Mục đích: Vẽ intro game, vẽ hình nhân vật game, vẽ bông hoa

+ Ý tưởng: Sử dụng thuật toán scanline để tô màu

+ Code

    void totron(Graphics g, intxc, intyc, intr) {

         intr2=r-1;

         while(r2>0){

             dtron(g,xc,yc,r2);

             r2--;

         }

    }