首先在鼠标左键按下里,记录下起点
然后再鼠标移动事件里,记录下鼠标当前位置,用一个数组保存,同时绘制出这个点和上个点间的线段。
最后在鼠标抬起事件里,完成点坐标的记录。
需要在重绘函数里添加整个轨迹的绘制 *** 作,这样绘制的轨迹不会被擦除。
若要实现CAD交互绘图的拖拽效果,可以使用SetROP2这个函数。
// 6.Bresenham画线算法.cpp#pragma comment(lib, "openGL32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
#include<iostream.h>// cout,cin
#include<math.h>// abs
#define GLUT_DISABLE_ATEXIT_HACK
#include<glut.h>
int x0,y01,xEnd,yEnd// 全局变量(y0与math.h中的变量重名,故用y01代替)
int width=400,height=400
void setPixel(GLint x,GLint y) // OpenGL画点函数
{
glBegin(GL_POINTS)// 开始画点
glVertex2i(x,y)// 根据2个整型值画1个点
glEnd()// 结束画点
}
void lineBresenham()
{ // Bresenham画线算法。其中x0,y01,xEnd,yEnd是全局变量
int dx=xEnd-x0,dy=yEnd-y01// Δx,Δy
int x,y,p
int twoDy,twoDyMinusDx,twoDyAddDx// 2Δy,2(Δy-Δx)
glClear(GL_COLOR_BUFFER_BIT)// 清除原显示窗口,让新显示窗口出现(颜色缓存)
if(dy==0) // m=0,水平线,x坐标每次增1,y不变
{
if(x0>xEnd) // (x0,y01)为右端点
x=xEnd
xEnd=x0
x0=x
}
else // (x0,y01)为左端点
x=x0// 令(x,y01)指示左端点
while(x<=xEnd)
{
setPixel(x,y01)
x++
}
}
else if(dx==0) // m=∞,垂直线,y坐标每次增1,x不变
{
if(y01>yEnd) // (x0,y01)为下端点
{ // 交换两端的坐标,并令(x0,y)指示上端点
y=yEnd
yEnd=y01
y01=y
}
else // (x0,y01)为上端点
y=y01// 令(x0,y)指示上端点
while(y<=yEnd)
{
setPixel(x0,y)
y++
}
}
else if(dx==dy) // 45度(撇),m=1,x、y坐标每次各增1
{
if(x0>xEnd) // (x0,y01)为右端点
{ // 交换两端的坐标,并令(x,y)指示左端点
x=xEnd
y=yEnd
xEnd=x0
yEnd=y01
x0=x
y01=y
}
else // (x0,y01)为左端点
{ // 令(x,y)指示左端点
x=x0
y=y01
}
while(x<=xEnd)
{
setPixel(x,y)
x++
y++
}
}
else if(dx==-dy) // -45度(捺),m=-1,x坐标每次增1,y坐标每次减1
{
if(x0>xEnd) // (x0,y01)为右端点
{ // 交换两端的坐标,并令(x,y)指示左端点
x=xEnd
y=yEnd
xEnd=x0
yEnd=y01
x0=x
y01=y
}
else // (x0,y01)为左端点
{ // 令(x,y)指示左端点
x=x0
y=y01
}
while(x<=xEnd)
{
setPixel(x,y)
x++
y--
}
}
else if(abs(dx)>abs(dy)) // 0<|m|<1.0,x坐标每次增1
{
if(x0>xEnd) // (x0,y01)为右端点
{ // 交换两端的坐标,并令(x,y)指示左端点
x=xEnd
y=yEnd
xEnd=x0
yEnd=y01
x0=x
y01=y
dx=-dx// Δx
dy=-dy// Δy
}
else // (x0,y01)为左端点
{ // 令(x,y)指示左端点
x=x0
y=y01
}
twoDy=2*dy// 2Δy
twoDyMinusDx=2*(dy-dx)// 2(Δy-Δx)
twoDyAddDx=2*(dy+dx)// 2(Δy+Δx)
if(dy>0) // 0<m<1.0
{
p=2*dy-dx// p0=2Δy-Δx
while(x<=xEnd)
{
setPixel(x,y)
x++
if(p<0)
p+=twoDy
else
{
y++
p+=twoDyMinusDx
}
}
}
else // -1<m<0
{
p=2*dy+dx// p0=2Δy+Δx
while(x<=xEnd)
{
setPixel(x,y)
x++
if(p<0)
{
y--
p+=twoDyAddDx
}
else
p+=twoDy
}
}
}
else if(abs(dx)<abs(dy)) // 1.0<|m|<∞,y坐标每次增1
{
if(y01>yEnd) // (x0,y01)为下端点
{ // 交换两端的坐标,并令(x,y)指示上端点
x=xEnd
y=yEnd
xEnd=x0
yEnd=y01
x0=x
y01=y
dx=-dx// Δx
dy=-dy// Δy
}
else // (x0,y01)为上端点
{ // 令(x,y)指示上端点
x=x0
y=y01
}
twoDy=2*dx// 2Δx
twoDyMinusDx=2*(dx-dy)// 2(Δx-Δy)
twoDyAddDx=2*(dx+dy)// 2(Δx+Δy)
if(dx>0) // 1.0<m<∞
{
p=2*dx-dy// p0=2Δx-Δy
while(y<=yEnd)
{
setPixel(x,y)
y++
if(p<0)
p+=twoDy
else
{
x++
p+=twoDyMinusDx
}
}
}
else // -1<m<0
{
p=2*dx+dy// p0=2Δx+Δy
while(y<=yEnd)
{
setPixel(x,y)
y++
if(p<0)
{
x--
p+=twoDyAddDx
}
else
p+=twoDy
}
}
}
glFlush()// 尽可能快地处理画图
}
void main(int argc,char** argv) // 可不输入参数
{
cout<<"请输入x0 y0 xEnd yEnd:"<<endl
cin>>x0>>y01>>xEnd>>yEnd
glutInit(&argc,argv)// 初始化GLUT
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB)// 设置窗口的缓存和颜色模型
glutInitWindowPosition(0,0)// 设置窗口左上角的坐标(在屏幕左上角)
glutInitWindowSize(width,height)// 设置窗口的大小
glutCreateWindow("画线算法1")// 创建窗口,并在标题栏显示字符串
glClearColor(1.0, 1.0, 1.0, 0.0)// 设置白色背景(R,G,B,透明),默认为黑色
glColor3f(1.0, 0.0, 0.0)// 用3个浮点数表示前景色(红),默认为白色
glMatrixMode(GL_PROJECTION)// 对三维图形作正投影
glLoadIdentity()// 初始化模型变换矩阵
gluOrtho2D(0.0,width,0.0,height)// 二维笛卡尔坐标系,x和y的起止坐标
glutDisplayFunc(lineBresenham)// 显示画线函数lineBresenham()
glutMainLoop()// 程序的最后一个函数,激活窗口及图形。使程序进入检查鼠标键盘的循环中
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)