|
#include <windows.h>
#include <gl/glut.h>
#include <stdio.h>
#include <math.h>
#define width 700.0
#define height 700.0
void Calc_Vertex(); // Vertex calculation func
void DoDisplay(); // display func
void DoMouseClick(int button, int state, int x, int y); // mouse click func (button - left middle right, state- clicked or not, xpos, ypos)
void DoMouseMotion(int x_mouse_cur, int y_mouse_cur); // mouse move func
void Record_XYposition(int x, int y); // Record previous mouse position
const double Pi = 3.14159265358979323846; // PI
int x_prev, y_prev; // previous Center of Pentagon
int mouse_button_flag = 0; // mouse button flag
int T = 10.0f;
struct{
GLfloat size; // Pentagon size
GLfloat Angle; // Pentagon angle
GLdouble Center_x, Center_y; // center of pentagon
GLdouble x[5], y[5]; // vertices (clockwise)
}Pentagon;
void Record_XYposition(int x, int y) // Record previous mouse position
{
x_prev = x;
y_prev = y;
}
void DoMouseClick(int button, int state, int x, int y) // mouse click event
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { // left button down
mouse_button_flag = 1; // make flag 1
Record_XYposition(x,y); // save x y position
}
else if(button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) { // right button down
mouse_button_flag = 2; // make flag 2
Record_XYposition(x,y); // save x y position
}
else if(button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) { // middle button down
mouse_button_flag = 3; // make flag 3
Record_XYposition(x,y); // save x y position
}
else // mouse button up
{
mouse_button_flag = 0;
}
}
void Rotate(void)
{
// x' = x cos f - y sin f
// y' = y cos f + x sin f
Pentagon.x[0] = ((Pentagon.x[0] - Pentagon.Center_x) * cos(T*Pi/180)) - ((Pentagon.y[0] - Pentagon.Center_y) * sin(T*Pi/180)) + Pentagon.Center_x;
Pentagon.y[0] = ((Pentagon.y[0] - Pentagon.Center_y) * cos(T*Pi/180)) + ((Pentagon.x[0] - Pentagon.Center_x) * sin(T*Pi/180)) + Pentagon.Center_y;
Pentagon.x[1] = ((Pentagon.x[1] - Pentagon.Center_x) * cos(T*Pi/180)) - ((Pentagon.y[1] - Pentagon.Center_y) * sin(T*Pi/180)) + Pentagon.Center_x;
Pentagon.y[1] = ((Pentagon.y[1] - Pentagon.Center_y) * cos(T*Pi/180)) + ((Pentagon.x[1] - Pentagon.Center_x) * sin(T*Pi/180)) + Pentagon.Center_y;
Pentagon.x[2] = ((Pentagon.x[2] - Pentagon.Center_x) * cos(T*Pi/180)) - ((Pentagon.y[2] - Pentagon.Center_y) * sin(T*Pi/180)) + Pentagon.Center_x;
Pentagon.y[2] = ((Pentagon.y[2] - Pentagon.Center_y) * cos(T*Pi/180)) + ((Pentagon.x[2] - Pentagon.Center_x) * sin(T*Pi/180)) + Pentagon.Center_y;
Pentagon.x[3] = ((Pentagon.x[3] - Pentagon.Center_x) * cos(T*Pi/180)) - ((Pentagon.y[3] - Pentagon.Center_y) * sin(T*Pi/180)) + Pentagon.Center_x;
Pentagon.y[3] = ((Pentagon.y[3] - Pentagon.Center_y) * cos(T*Pi/180)) + ((Pentagon.x[3] - Pentagon.Center_x) * sin(T*Pi/180)) + Pentagon.Center_y;
Pentagon.x[4] = ((Pentagon.x[4] - Pentagon.Center_x) * cos(T*Pi/180)) - ((Pentagon.y[4] - Pentagon.Center_y) * sin(T*Pi/180)) + Pentagon.Center_x;
Pentagon.y[4] = ((Pentagon.y[4] - Pentagon.Center_y) * cos(T*Pi/180)) + ((Pentagon.x[4] - Pentagon.Center_x) * sin(T*Pi/180)) + Pentagon.Center_y;
}
void DoMouseMotion(int x_mouse_cur, int y_mouse_cur)
{
if(mouse_button_flag == 1) // when Left button clicked
{
//Rotate();
//T = (x_prev - x_mouse_cur);
//Record_XYposition(x_mouse_cur,y_mouse_cur); // save x y position.
char pos_info[128];
sprintf(pos_info, "x0=%.2f,y0=%.2f", Pentagon.x[0], Pentagon.y[0]); // present x y position (window title)
glutSetWindowTitle(pos_info);
glutPostRedisplay(); // call display func
}
if(mouse_button_flag == 2) // when Right button clicked
{
/*
When mouse is moving, get the difference between previous position and currunt position.
x gap => (x_mouse_cur - Center_x_prev)
y gap => (Center_y_prev - y_mouse_cur)
those two will be come out by Integer becouse win32 and Opengl has different pixel type.
so we need to adjust.
(x_mouse_cur - Center_x_prev)/(Width of windows/2)
(Center_y_prev - y_mouse_cur)/(Height of windows/2)
win32 Opengl
!-------! !-------!
!(0,0) ! ! !
! ! -1 ! (0,0) ! 1
! ! ! !
!_______!(Width,Height) !-------!
*/
Pentagon.Center_x += (x_mouse_cur - x_prev)/(width/2);
Pentagon.Center_y += (y_prev - y_mouse_cur)/(height/2);
Record_XYposition(x_mouse_cur,y_mouse_cur); // save x y position.
char pos_info[128];
sprintf(pos_info, "[Right Button] CENTER x=%.2f, y=%.2f", Pentagon.Center_x, Pentagon.Center_y); // present x y position (window title)
glutSetWindowTitle(pos_info);
glutPostRedisplay(); // call display func
}
else if(mouse_button_flag == 3) // Middle button clicked
{
Pentagon.size += (x_mouse_cur - x_prev)/(width/2); // increase Pentagon size
if(Pentagon.size <= 0.05) // if size smaller than 0.05 it will be fixed
{
Pentagon.size = 0.05;
}
Record_XYposition(x_mouse_cur,y_mouse_cur); // save x y position.
char size_info[128];
sprintf(size_info, "[Middle Button] SIZE x=%.2f", Pentagon.size); // present x y position (window title)
glutSetWindowTitle(size_info);
glutPostRedisplay(); // call display func
}
}
void Calc_Vertex() // Vertex calculation func
{
/*
0,0
4,4 1,1
3,3 2,2
*PLEASE SEE JPG FILE I ATTATCHED HOW TO CALC EACH VERTEX
*/
if(mouse_button_flag == 1)
{
Rotate();
}
else
{
Pentagon.x[0] = Pentagon.Center_x;
Pentagon.y[0] = Pentagon.Center_y+Pentagon.size;
Pentagon.x[1] = Pentagon.Center_x+(Pentagon.size*sin(Pentagon.Angle*Pi/180));
Pentagon.y[1] = Pentagon.Center_y+(Pentagon.size*cos(Pentagon.Angle*Pi/180));
Pentagon.x[2] = Pentagon.Center_x+(Pentagon.size*cos((90-(Pentagon.Angle/2))*Pi/180));
Pentagon.y[2] = Pentagon.Center_y-(Pentagon.size*sin((90-(Pentagon.Angle/2))*Pi/180));
Pentagon.x[3] = Pentagon.Center_x-(Pentagon.size*cos((90-(Pentagon.Angle/2))*Pi/180));
Pentagon.y[3] = Pentagon.Center_y-(Pentagon.size*sin((90-(Pentagon.Angle/2))*Pi/180));
Pentagon.x[4] = Pentagon.Center_x-(Pentagon.size*sin(Pentagon.Angle*Pi/180));
Pentagon.y[4] = Pentagon.Center_y+(Pentagon.size*cos(Pentagon.Angle*Pi/180));
}
}
void DoDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON); // to make pentagon
Calc_Vertex(); // call calc vertex func
glColor3f(1.0, 0.0, 0.0); // to make colour RGB =>R
glVertex2d(Pentagon.x[0],Pentagon.y[0]); // x1 y1
glVertex2d(Pentagon.x[1],Pentagon.y[1]); // x2 y2
glColor3f(0.0, 1.0, 0.0); // to make colour RGB =>G
glVertex2d(Pentagon.x[2],Pentagon.y[2]); // x3 y3
glColor3f(0.0, 0.0, 1.0); // to make colour RGB =>B
glVertex2d(Pentagon.x[3],Pentagon.y[3]); // x4 y4
glVertex2d(Pentagon.x[4],Pentagon.y[4]); // x5 y5
glEnd();
glFlush();
}
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszCmdParam,int nCmdShow)
{
Pentagon.size = 0.3; // define Pentagon size
Pentagon.Angle = 72; // Pentagon Angle 360/5 = 72
Pentagon.Center_x = 0; // Initialize pentagon center x,y
Pentagon.Center_y = 0;
glutInitWindowSize(width, height);
glutCreateWindow("OpenGL");
glutDisplayFunc(DoDisplay); // Display func
glutMouseFunc(DoMouseClick); // Mouse Click func
glutMotionFunc(DoMouseMotion); // Mouse Motion func
glutMainLoop();
return 0;
}
위의 소스에서 5각형을 회전시킬 때 문제가 발생하는데요
실행파일을 올렸다시피 마우스 왼쪽버튼이 눌리고있을때 움직이면 회전되게 만들려하는데
이상하게 계속 도형이 줄어드네요....
나중에 5각형 꼭지점들을 텍스트 파일로 저장하고 불러와야 하기때문에 그냥 이미지만 회전하면 안될거같고
점들의 위치를 알아내서 그려줘야 할것같은데
왜 회전될때 수축되는지 모르겠네요...
능력자님들 도와주세요;;
|