MFC bresenham直线算法与MidPoint画圆的总结
来源:互联网 发布:淘宝买ps3是新机吗 编辑:程序博客网 时间:2024/06/07 15:50
首先看一下效果图!!
vs2017做的,我觉得跟vc6上做都是一样的。
在MFC的view.h头文件和view.cpp 里新建自己的函数,
void CMFC1View::Bresenhamline(int x0, int y0, int x1, int y1, int color)
{
{
CDC *p;
p = GetDC();
int x, y, dx, dy, e;
p = GetDC();
int x, y, dx, dy, e;
dx = x1 - x0;
dy = y1 - y0;
dy = y1 - y0;
e = -dx;
x = x0;
y = y0;
x = x0;
y = y0;
if ((dx >= 0 && dy >= 0) || (dx <= 0 && dy <= 0)) //如果k大于0
{
if ((dx<0) || (dx == 0 && dy<0)) //dx小于0说明终点x
{
dx = -dx;//
x = x1;//
dy = -dy;
y = y1;
{
if ((dx<0) || (dx == 0 && dy<0)) //dx小于0说明终点x
{
dx = -dx;//
x = x1;//
dy = -dy;
y = y1;
}
if (dy<dx) //第一种情况,k-(0,1)//////////////
{
e = -dx;
for (int i = 0;i<dx;i++)
{
p->SetPixel(x, y, color);
x++;
e = e + dy + dy;
if (e >= 0)
{
y++;
e = e - dx - dx;
}
}
}
else //第二种情况,k-(1,max)
{
e = -dy;
for (int i = 0;i<dy;i++)
{
p->SetPixel(x, y, color);
y++;
e = e + dx + dx;
if (e >= 0)
{
x++;
e = e - dy - dy;
}
}
}
}
else //如果k小于0
{
int tempx, tempy; //保存x和y的绝对值
if (dx<0) //dx小于0说明终点x
{
tempx = -dx;
tempy = dy;
}
if (dy<0)
{
tempx = dx;
tempy = -dy;
}
if (dy<dx) //第一种情况,k-(0,1)//////////////
{
e = -dx;
for (int i = 0;i<dx;i++)
{
p->SetPixel(x, y, color);
x++;
e = e + dy + dy;
if (e >= 0)
{
y++;
e = e - dx - dx;
}
}
}
else //第二种情况,k-(1,max)
{
e = -dy;
for (int i = 0;i<dy;i++)
{
p->SetPixel(x, y, color);
y++;
e = e + dx + dx;
if (e >= 0)
{
x++;
e = e - dy - dy;
}
}
}
}
else //如果k小于0
{
int tempx, tempy; //保存x和y的绝对值
if (dx<0) //dx小于0说明终点x
{
tempx = -dx;
tempy = dy;
}
if (dy<0)
{
tempx = dx;
tempy = -dy;
}
if (tempx>tempy) //第三种情况,k-(-1,0)
{
if (dx<0) //dx小于0说明终点x
{
dx = -dx;
x = x1;
dy = -dy;
y = y1;
}
e = -dx;
for (int i = 0;i<dx;i++)
{
p->SetPixel(x, y, color);
x++;
e = e - dy - dy;
if (e >= 0)
{
y--;
e = e - dx - dx;
}
}
}
else //第四种情况,k-(-1,min)
{
if (dy<0)//dx小于0说明终点x
{
dx = -dx;
x = x1;
dy = -dy;
y = y1;
}
e = -dy;
for (int i = 0;i<dy;i++)
{
p->SetPixel(x, y, color);
y++;
e = e - dx - dx;
if (e >= 0)
{
x--;
e = e - dy - dy;
}
}
}
}
{
if (dx<0) //dx小于0说明终点x
{
dx = -dx;
x = x1;
dy = -dy;
y = y1;
}
e = -dx;
for (int i = 0;i<dx;i++)
{
p->SetPixel(x, y, color);
x++;
e = e - dy - dy;
if (e >= 0)
{
y--;
e = e - dx - dx;
}
}
}
else //第四种情况,k-(-1,min)
{
if (dy<0)//dx小于0说明终点x
{
dx = -dx;
x = x1;
dy = -dy;
y = y1;
}
e = -dy;
for (int i = 0;i<dy;i++)
{
p->SetPixel(x, y, color);
y++;
e = e - dx - dx;
if (e >= 0)
{
x--;
e = e - dy - dy;
}
}
}
}
}
在view.cpp里重载鼠标的左键按下和弹起两个函数,在view.h 定义公有的cpoint x1,x2;
void CMFC1View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
x1 = point;
CView::OnLButtonDown(nFlags, point);
}
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
x1 = point;
CView::OnLButtonDown(nFlags, point);
}
void CMFC1View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
x2 = point;
Bresenhamline(x1.x,x1.y,x2.x,x2.y,255);//直接调用函数,不会重绘制,
CView::OnLButtonUp(nFlags, point);
}
然后在鼠标弹起的函数里调用就行,也可以先调用invalidate()函数,invalidate()函数会自动调用ondraw()函数,区别是一个是ondraw()里调的后面的会覆盖前面的,直接调用的不会覆盖原来的画出来的直线或者圆。哪个都行,看你的需要。
void CMFC1View::OnDraw(CDC* pDC)
{
CMFC1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(m_nshape==1)
Bresenhamline(x1.x, x1.y, x2.x, x2.y, 255);//ondraw()里调用会覆盖前面画的图
if (m_nshape == 2)
{
radius = (x2.y - x1.y)*(x2.y - x1.y) + (x2.x - x1.x)*(x2.x - x1.x);
radius = sqrt(radius);
MidPointCircle(x1.x, x1.y, radius, 255);
}
// TODO: 在此处为本机数据添加绘制代码
}
{
CMFC1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if(m_nshape==1)
Bresenhamline(x1.x, x1.y, x2.x, x2.y, 255);//ondraw()里调用会覆盖前面画的图
if (m_nshape == 2)
{
radius = (x2.y - x1.y)*(x2.y - x1.y) + (x2.x - x1.x)*(x2.x - x1.x);
radius = sqrt(radius);
MidPointCircle(x1.x, x1.y, radius, 255);
}
// TODO: 在此处为本机数据添加绘制代码
}
以上是直线的输出两种方法哪个都行。
--------------------------------------------------------------------------
直线的函数是可以直接调用的,但是圆的函数涉及到,求半径的问题,所以我在头文件的公有数据里定义了radius,方便直接调用,
圆的view.h 和view.cpp里定义两个函数。
int CMFC1View::DrawPoint(int x0, int y0, int x, int y, int color)
{
CDC *PDc = GetDC();
{
CDC *PDc = GetDC();
PDc->SetPixel(x + x0, y + y0, 255);
PDc->SetPixel(-x + x0, y + y0, 255);
PDc->SetPixel(-x + x0, -y + y0, 255);
PDc->SetPixel(x + x0, -y + y0, 255);
PDc->SetPixel(y + x0, x + y0, 255);
PDc->SetPixel(-y + x0, x + y0, 255);
PDc->SetPixel(-y + x0, -x + y0, 255);
PDc->SetPixel(y + x0, -x + y0, 255);
return (0);
}
void CMFC1View::MidPointCircle(int x0, int y0, int radus, int color)
{
}
void CMFC1View::MidPointCircle(int x0, int y0, int radus, int color)
{
int x, y, d;
x = 0;y = radus;d = int(1.25 - radus);
while (y >= x)
{
DrawPoint(x0, y0, x, y, color);
if (d<0)
{
d = d + 2 * x + 3;x++;
}
else
{
d = d + 2 * (x - y) + 5;x++;y--;
}
}
}
x = 0;y = radus;d = int(1.25 - radus);
while (y >= x)
{
DrawPoint(x0, y0, x, y, color);
if (d<0)
{
d = d + 2 * x + 3;x++;
}
else
{
d = d + 2 * (x - y) + 5;x++;y--;
}
}
}
圆的两个函数,一个是定义八分之一的圆,另一个函数负责画出对称点,
radius=sqrt((x2.y-x1.y)*(x2.y-x1.y)+(x2.x-x1.x)*(x2.x-x1.x));
记得加上#include<cmath>
再把圆心和半径传进去进行,
invalidate()这个函数会自动调用ondraw() 函数,
如果不涉及到菜单项就不用invalidate() 调用ondraw()函数,而是 直接在你需要的地方调用该函数就行。
希望对你有帮助,
0 0
- MFC bresenham直线算法与MidPoint画圆的总结
- 直线的Bresenham算法
- bresenham 画直线算法
- Bresenham 画直线算法
- Bresenham算法画直线
- Bresenham算法画直线
- Bresenham直线算法的实现
- 生成直线的Bresenham算法
- 生成直线的Bresenham算法
- 生成直线的Bresenham算法
- 图形学算法--Bresenham画直线
- Bresenham快速画直线算法
- Bresenham快速画直线算法
- Bresenham快速画直线算法
- LCD160160 Bresenham算法 画直线
- Bresenham快速画直线算法
- 应用Bresenham算法画直线。
- Bresenham快速画直线算法
- 触发器1
- Java面试题集(四)
- 单一事件中心管理组件通信
- Testlink环境搭建
- linux下用户管
- MFC bresenham直线算法与MidPoint画圆的总结
- MFC按客户区大小获取合适的主窗口大小
- swust oj2611
- Java面试题集(五)
- web.鼠标.阻止冒泡
- Node.js 适配器模式
- Svn环境搭建
- 虚拟机下三种网络模式
- 碎片知识点-01