#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <glut.h>
#define N 1000 //maximum line numbers
int ww=800,hh=600; // for display window width and height
int line[N][4], k=0; //for line's endpoint coordinates and line number
int flag=1,draw=1;
int rx1,rx2,ry1,ry2;
class Point2D
{
public:
float x;
float y;
};
Point2D p1,p2,winMin,winMax;
void Myinit();
void myMouse(int button,int state,int x,int y);
void myMotion(int x,int y);
void drawlines();
void Display(void);
void Reshape(int w, int h);
void Keyboard(unsigned char key, int x, int y);
void drawbox();
void clipLine (Point2D winMin, Point2D winMax, Point2D p1, Point2D p2);
int clipTest (float p, float q, float * u1, float * u2);
void clipping();
void Myinit(void)
{
glClearColor(1.0,1.0,1.0,0.0);
glLineWidth(1.0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glEnable(GL_POLYGON_SMOOTH);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
//鼠标...............................................................................................................................
void myMouse(int button,int state,int x,int y)
{
if (flag==1)
{
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
{
// get the line's start point
line[k][0]=x;
line[k][1]=hh-y;
}
if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP)
{
// get the line's end point , count lines's number
line[k][2]=x;
line[k][3]=hh-y;
k++;
glutPostRedisplay();
}
}
if (flag==2)
{
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
{
// get the line's start point
rx1=x;
ry1=hh-y;
}
if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP)
{
// get the line's end point , count lines's number
rx2=x;
ry2=hh-y;
draw=2;
glutPostRedisplay();
}
}
}
//-----------------获得鼠标移动中的坐标-----------------------------------------------------------
void myMotion(int x,int y)
{
if (flag==1)
{
line[k][2]=x;
line[k][3]=hh-y;
glutPostRedisplay();
}
if (flag==2)
{
rx2=x;
ry2=hh-y;
glutPostRedisplay();
}
}
void drawlines()
{
glColor3f(0,0,1);
for(int i=0;i<=k;i++) //********
{
glBegin(GL_LINES);
glVertex2f(line[i][0],line[i][1]);
glVertex2f(line[i][2],line[i][3]);
glEnd();
}
}
//画图---------------------------------------------------------------------------------------------------
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
if (flag==1)
drawlines();
if (flag==2)
{
if (draw==1)
{
drawlines();
drawbox();
}
else
{
draw=1;
clipping();
drawbox();
for (int i=0;i<=k;i++)
{
line[i][0]=0;
line[i][1]=0;
line[i][2]=0;
line[i][3]=0;
}
k=0;
rx1=0,rx2=0,ry1=0,ry2=0;
}
/*drawlines();
drawbox();*/
}
glutSwapBuffers();
}
//-----------------------------------------------
void Reshape(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluOrtho2D(0, w, 0, h);
ww=w;
hh=h;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(ww,hh);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Draw Lines by Mouse");
Myinit();
glutDisplayFunc(Display);
glutKeyboardFunc(Keyboard);
glutMouseFunc(myMouse);
glutMotionFunc(myMotion);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}
void Keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case '1':
flag=1;
break;
case '2':
flag=2;
break;
}
glutPostRedisplay(); //参数修改后调用重画函数,屏幕图形将发生改变
}
void drawbox()
{
glRectf(rx1,ry1,rx2,ry2);
}
void clipLine (Point2D winMin, Point2D winMax, Point2D p1, Point2D p2)
{
float u1 =0.0, u2 =1.0, dx= p2.x - p1.x, dy;
if (clipTest(-dx, p1.x- winMin.x, &u1, &u2))
if (clipTest(dx, winMax.x-p1.x, &u1, &u2)) {
dy = p2.y-p1.y;
if (clipTest(-dy, p1.y-winMin.y, &u1, &u2))
if (clipTest(dy, winMax.y-p1.y, &u1, &u2)) {
if (u2 < 1.0) {
p2.x = p1.x + u2 * dx;
p2.y = p1.y + u2 * dy;
}
if (u1 > 0.0) {
p1.x += u1 * dx;
p1.y += u1 * dy;
}
// line DDA (ROUND (p1 .x), ROUND(p1 .y), ROUND(p2 .x) , ROUND(p2 . y));
glBegin(GL_LINES);
glVertex2f(p1.x,p1.y);
glVertex2f(p2.x,p2.y);
glEnd();
}
}
}
int clipTest (float p, float q, float * u1, float * u2)
{
float r; int retVal = TRUE;
if (p < 0.0) {
r = q/p;
if (r > *u2) retVal = FALSE;
else
if (r > *u1) *u1 = r;
}
else
if (p >0.0) {
r = q / p;
if (r < *u1) retVal = FALSE;
else if (r < *u2) *u2 = r;
}
else
/* p = 0, so line is parallel to this clipping edge */
if (q < 0.0)
/* Line is outside clipping edge */
retVal = FALSE;
return (retVal) ;
}
void clipping()
{
if (rx1>=rx2)
{ winMin.x=rx2; winMax.x=rx1;}
else
{ winMin.x=rx1; winMax.x=rx2;}
if (ry1>=ry2)
{ winMin.y=ry2; winMax.y=ry1;}
else
{ winMin.y=ry1; winMax.y=ry2;}
for(int i=0;i<=k;i++) //********
{
p1.x=line[i][0];
p1.y=line[i][1];
p2.x=line[i][2];
p2.y=line[i][3];
clipLine( winMin, winMax, p1, p2);
}
}
OpenGL c++ 鼠标键盘交互 梁友栋算法 裁剪
5星 · 超过95%的资源 需积分: 12 75 浏览量
2009-12-10
16:41:45
上传
评论 6
收藏 1.98MB RAR 举报
xvhuihui123
- 粉丝: 2
- 资源: 5
- 1
- 2
前往页