Code vẽ đường tròn, elip C++

Sau đây xin trình bày vẽ hình tròn, elip bằng C++ với thuật toán midpoint.

Những lập trình viên muốn tìm hiểu về thuật toán về các đường cơ bản trong đồ họa máy tính.

Tìm hiểu thuật toán Midpoint Đường tròn có tâm O(xc, yc) = (0, 0), bán kinh r có phương trình:

x2 + y2 = r2 => x2 + y2 - r2 = 0

Đặt f(x, y) = x2 + y2 - r2

Với mọi điểm P(x, y) nằm trong hệ tọa độ Oxy, ta có:

P(x, y) nằm trên đường tròn O nếu f(x, y) = 0 P(x, y) nằm ngoài đường tròn O nếu f(x, y) > 0 P(x, y) nằm trong đường tròn O nếu f(x, y)< 0

Tròn

Do đường tròn có tính đối xứng qua các cũng 1/8, nghĩa là ứng với một điểm có tọa độ (x, y) thuộc 1 cung nào đó, ta có thể hoàn toàn xác định được tọa độ 7 điểm còn lại bằng cách lấy đối xứng qua các cung.

Từ tính chất đó nên chúng ta chỉnh cần vẽ 1/8 đường tròn là đủ, sau đó sẽ lấy đối xứng để được đường tròn hoàn chỉnh.

Điểm đầu tiên ta vẽ là điểm (x = 0, y = R)

Trong cung 1/8 thứ nhất do khoảng biến thiên của x lớn hơn khoảng biến thiên của y, nên xi+1 = xi + 1.

Giả sử ta đã vẽ được (Xi, Yi) ở bước thứ i, ta cần xác định (Xi+1, Yi+1) ở bước thứ i + 1.

Như vậy ta có:

ss_2

Ta có hình như sau: Tròn2

Tính Fi Đặt Fi = F(X, Y - 1/2), ta hình có công thức:

ss_4

Nếu Fi < 0 <=> (Xi + 1, Y) gần với Yi => Yi+1 = Yi

Nếu Fi >= 0 <=> (Xi + 1, Y) gần với Yi - 1 => Yi + 1 = Yi -1

Tính Fi +1 theo Fi Fi + 1 - Fi = 2Xi + 3 + (Yi+12 - Yi2) + (Yi+1 - Yi) (*)

Nếu Fi < 0 thì Fi + 1 = Fi + 2Xi + 3, do ta thay thế Yi+1 = Yi vào (*)

Nếu Fi >= 0 thì Fi + 1 = Fi + 2(Xi - Yi) + 5, do thay thế Yi+1 = Yi -1 vào (*)

Tính giá trị F đầu tiên Ta có:

ss_4

Thay Xi = 0 và Yi = R trong công thức trên ta có được: F = 5/4 - R

Sau đây Hiện thực thuật toán Midpoint vẽ hình tròn ta có code sau:

 Veduongtron_elip.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "glut.h"
#include 
#include 
int screenWidth=640;//kich thuoc chieu rong man hinh
int screenHeight=640;//kich thuoc chieu cao man hinh
typedef struct
{ 
	GLint x1,y1;
	GLint x2,y2;
} GLintPoint;//tao cau truc du lieu luu 2 toa do
#define NUM 100// khai bao kich thuoc mang
GLintPoint list[NUM];//mang chua toa do cua hinh elip
GLintPoint list1[NUM];//mang chua toa do cua hinh tron
int last=-1;//trang thai ban dau cua mang elip =-1
int last1=-1;//tuong tu hinh tron
int xt1,xt2,yt1,yt2;//khai bao toa do lay tu chuot de ve elip
int xt1c,xt2c,yt1c,yt2c;//tuong tu hinh tron
//ham hoan vi de chuyen doi toa do
void hoanvi(int &x,int &y)
{
	int tam;
	tam=x;
	x=y;
	y=tam;
}
//tao man hinh nen
void DinhDangNen(GLsizei w,GLsizei h)
{    
    glClearColor(0.0,0.0,0.0,0.0); //Set mau nen la den
    glPointSize(1.0); // Kich thuoc 1 diem
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,screenWidth, 0.0, screenHeight);//tao kich thuoc man hinh hien thi
    glClear(GL_COLOR_BUFFER_BIT);
}
//ve doi xung 8 dinh
void put8pixel(int xc,int yc,int x,int y)
 {
		glColor3f(0.0f, 0.4f, 1.0f);
        glBegin(GL_POINTS);
            glVertex2i(xc+x,yc+y);
            glVertex2i(xc-x,yc+y);
            glVertex2i(xc+x,yc-y);
            glVertex2i(xc-x,yc-y);
            glVertex2i(xc+y,yc+x);
            glVertex2i(xc-y,yc+x);
            glVertex2i(xc+y,yc-x);
            glVertex2i(xc-y,yc-x);
            
        glEnd();
   }
//ve hinh tron thuat toan midpoint,toa do chuot dau tien,toa do chuot thu 2
void c_mid(int xc1,int yc1,int xc2,int yc2)
 {
		//hoan vi toa do
		if(xc1>xc2)
		{
				hoanvi(xc1,xc2);
			if(yc1>yc2)
	 			hoanvi(yc1,yc2);
		}
		if(xc1if(yc1>yc2)
				hoanvi(yc1,yc2);
		int xc,yc;
		xc=(xc1+xc2)/2;//tinh tam x duong tron
		yc=(yc1+yc2)/2;//tinh  tam y duong tron
		int r=(xc1+xc2)/2-xc1;//tinh ban kinh
		int x=0;
        int y=r;
        int p=(1-r);
        while(x<=y)
        {
            put8pixel(xc,yc,x,y);
            x++;
            if(p<0)
                p+=((2*x)+3);
            else
            {
                y--;
                p+=((2*(x-y))+5);
            }
        }
  }
//ve 1 diem
void Setpixel(int x,int y)
{
	glBegin(GL_POINTS);
	glVertex2i(x,y);
	glEnd();
}
//lay doi xung 4 dinh
void Set4pixel(int xc,int yc,int x,int y)
{
	Setpixel(xc+x,yc+y);
	Setpixel(xc+x,yc-y);
	Setpixel(xc-x,yc+y);
	Setpixel(xc-x,yc-y);
}

//elip thuat toan midpoint,truyen vao xc1,yc1 toa do chuot ban dau,xc2,yc2 toa do chuot luc sau
void E_mid(int xc1,int yc1,int xc2,int yc2)
{
	//can hoan vi toa do de luon luon x2>x1,y2>y1
	if(xc1>xc2)
	{
		hoanvi(xc1,xc2);
		if(yc1>yc2)
	 		hoanvi(yc1,yc2);
		
	}
	if(xc1if(yc1>yc2)
			hoanvi(yc1,yc2);
			
		
	
	int xc,yc;
	xc=(xc1+xc2)/2;//tinh tam x elip
	yc=(yc1+yc2)/2;//tinh tam y elip
	int a,b;
	
	a=(xc1+xc2)/2-xc1;//tinh a
	b=(yc1+yc2)/2-yc1;//tinh b
	int x,y;
	long p;
	long a2 = (long)a*a;
	long b2 = (long)b*b;
	long four_a2 = 4*a2;
	long four_b2 = 4*b2;
	
	x = 0;
	y = b;
	p = a2 - four_a2*b + four_b2;
	Set4pixel(xc,yc,x,y);
	while(a2*y>b2*x)
	{
		if(p>=0)
		{
			p+=four_b2*(2*x+3) - four_a2*(2*y-2);
			y--;
		}
		else
			p+=four_b2*(2*x+3);
		x++;
		Set4pixel(xc,yc,x,y);

	}
	
	x = a;
	y = 0;
	p = b2 - four_b2*a + four_a2;
	Set4pixel(xc,yc,x,y);
	while (b2*x>a2*y)
	{
		if(p>=0)
		{
			p+=four_a2*(2*y+3)-four_b2*(2*x-2);
			x--;
		}
		else
			p+=four_a2*(2*y+3);
		y++;
		Set4pixel(xc,yc,x,y);
	}

}
//xuat mang elip ra man hinh
void output()
{
	glClear(GL_COLOR_BUFFER_BIT);
	for(int i=0 ;i <=last;i++)
	{
		
		E_mid(list[i].x1,list[i].y1,list[i].x2,list[i].y2);//xuat mang elip da dc ve
	}
		
		E_mid(xt1,yt1,xt2,yt2);//xuat elip tam thoi
	for(int i=0;i <=last1;i++)
	{
		c_mid(list1[i].x1,list1[i].y1,list1[i].x2,list1[i].y2);//xuat mang hinh tron da dc ve
		
	}
		c_mid(xt1c,yt1c,xt2c,yt2c);//xuat hinh tron tam thoi
		
	glEnd();
	glutSwapBuffers();
}
//lay toa do chuot cua elip
void xulychuot(int button,int status,int x,int y)
{
	if(button==0&&status==0)
	{
		xt1=x;//lay toa do x dau tien
		yt1=screenHeight-y;//lay toa do y dau tien chuyen ve toa do binh thuong
	}
	//lay toa do sau cung,nhap vao mang va xuat ra
	if(button==0&&status==1)
	{
		xt2=x;
		yt2=screenHeight-y;
		E_mid(xt1,yt1,xt2,yt2);
		last++;
		list[last].x1=xt1;
		list[last].y1=yt1;
		list[last].x2=xt2;
		list[last].y2=yt2;
		output();
	}
	//khi nhap phai reset lai mang
	if(button==2 && status==0)
	{
		last=-1;
	}

}
//ham keo re chuotcua elip
void chuotdichuyen(int x,int y)
{
	glClear(GL_COLOR_BUFFER_BIT);
	xt2 = x;
	yt2 = screenHeight-y;
	output();
}
//xuat mang duong tron,hinh elip
void output1()
{
	glClear(GL_COLOR_BUFFER_BIT);
	for(int i=0;i <=last1;i++)
	{
		c_mid(list1[i].x1,list1[i].y1,list1[i].x2,list1[i].y2);
		
	}
		c_mid(xt1c,yt1c,xt2c,yt2c);
	for(int i=0;i <=last;i++)
	{
		
		E_mid(list[i].x1,list[i].y1,list[i].x2,list[i].y2);
	}
		
		E_mid(xt1,yt1,xt2,yt2);

		
	glEnd();
	glutSwapBuffers();
}
//xac dinh toa do chuot cua duongtron,tuong tu cua elip
void xulychuot1(int button,int status,int x,int y)
{
	if(button==0&&status==0)
	{
		xt1c=x;
		yt1c=screenHeight-y;
	}
	if(button==0&&status==1)
	{
		xt2c=x;
		yt2c=screenHeight-y;
		c_mid(xt1c,yt1c,xt2c,yt2c);
		last1++;
		list1[last1].x1=xt1c;
		list1[last1].y1=yt1c;
		list1[last1].x2=xt2c;
		list1[last1].y2=yt2c;
		output1();
	}
	if(button==2 && status==0)
	{
		last1=-1;
		
	}
}
//keo re chuot duong tron
void chuotdichuyen1(int x,int y)
{
	glClear(GL_COLOR_BUFFER_BIT);
	xt2c = x;
	yt2c = screenHeight-y;
	output1();
}
// xu ly phim e ve elip,c ve duong tron
void xulyphim(unsigned char key,int x,int y)
{
	
	
	switch(key)
	{
		case 'e':
			glutMouseFunc(xulychuot);
			glutMotionFunc(chuotdichuyen);
			glutDisplayFunc(output);
		
				break;
		case 'c':
			glutMouseFunc(xulychuot1);
			glutMotionFunc(chuotdichuyen1);
			glutDisplayFunc(output1);
				
			break;
		
			
	}
}

int _tmain(int argc, char* argv[])
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_DOUBLE);
	glutInitWindowSize(screenWidth,screenHeight);
	glutCreateWindow("ve duong tron Mid");
	glutDisplayFunc(output);
	glutReshapeFunc(DinhDangNen);
	glutKeyboardFunc(xulyphim);
	glutMainLoop();
	return 0;
}






Chủ đề liên quan
Code vẽ đường tròn, elip C++

Cùng chuyên mục

Xem nhiều hôm nay