2012.10.11 周四
来源:互联网 发布:ip网络功放系统图 编辑:程序博客网 时间:2024/05/21 19:27
计算机图形学
*********直线段的扫描转换算法*********
DDA算法:
算法分析参考《计算机图形学实用教程》的41页。
void DDALine(int x1,int y1,int x2,int y2,CDC *pDC)
{
int xLength=x2-x1;
int yLength=y2-y1;
int steps=abs(xLength)>abs(yLength)?abs(xLength):abs(yLength);
assert(steps!=0);
float xDis=xLength/(float)steps;
float yDis=yLength/(float)steps;
float x=x1; //如果将这里的x、y声明为int会画出不符合要求的直线
float y=y1;
pDC->SetPixel((int)x,(int)y,RGB(255,0,0));
for(int i=0;i<steps;i++)
{
x+=xDis;
y+=yDis;
pDC->SetPixel((int)(x+0.5),(int)(y+0.5),RGB(255,0,0));
}
}
中点画线法(Midpoint Line Drawing Algorithm):
过点(x0,y0)、(x1, y1)的直线段L的方程式为F(x, y)=ax+by+c=0,其中,a=y0-y1, b=x1-x0, c=x0y1-x1y0,欲判断中点M在Q点的上方还是下方,只要把M代入F(x,y),并判断它的符号即可。为此,我们构造判别式:
d=F(M)=F(xp+1, yp+0.5)=a(xp+1)+b(yp+0.5)+c
当d<0时,M在L(Q点)下方,取P2为下一个象素;
当d>0时,M在L(Q点)上方,取P1为下一个象素;
当d=0时,选P1或P2均可,约定取P1为下一个象素;
算法分析参考《计算机图形学实用教程》的43页,本算法改进过程中有两个重要思想:
1、增量法递推计算d.
2、d的增量都是整数,只是初始值包含小数.为了消除小数运算,取2d代替d.
void CLineDemoView::MidpointLine(CPoint p1,CPoint p2,CDC *pDC)
{
CPoint pointStart=p1,pointEnd=p2;
if(p1.x>p2.x)
{
pointStart=p2;
pointEnd=p1;
}
int a=pointStart.y-pointEnd.y,b=pointEnd.x-pointStart.x;
int x=pointStart.x,y=pointStart.y;
int d,deta1,deta2,cases,xDis=1,yDis=1;
if(a*b<0&&(a+b)*b>0)//0 <= k < 1
{
cases=0;
d=a*2+b;
deta1=a*2;
deta2=(a+b)*2;
}else if ((a+b)*b<=0)// k >= 1
{
cases=1;
d=a+b*2;
deta1=(a+b)*2;
deta2=b*2;
}else if((a-b)*b<=0)// -1 <= k < 0
{
cases=2;
d=a<<1;
deta1=(a-b)<<1;
deta2=a<<1;
}else if((a-b)*b>0)// k <= -1
{
cases=3;
d=a-b<<2;
deta1=(-b)<<1;
deta2=(a-b)<<1;
}else
{
MessageBox("K error!");
return;
}
int steps=(abs(pointEnd.y-pointStart.y)>abs(pointEnd.x-pointStart.x))?abs(pointEnd.y-pointStart.y):abs(pointEnd.x-pointStart.x);
for(int i=0;i<steps;i++)
{
if(d>=0)
{
switch(cases)
{
case 0:
x++;
break;
case 1:
x++;
y++;
break;
case 2:
x++;
y--;
break;
case 3:
y--;
break;
}
d+=deta1;
}else{
switch(cases)
{
case 0:
x++;
y++;
break;
case 1:
y++;
break;
case 2:
x++;
break;
case 3:
x++;
y--;
break;
}
d+=deta2;
}
pDC->SetPixel(x,y,RGB(255,0,0));
}
}
Bresenham画线法(B算法):
void CCgLSCDemoView::BresenhamLine(int x1, int y1, int x2, int y2, CDC *pDC) {
int dx = abs(x2 - x1),
dy = abs(y2 - y1),
yy = 0; // yy=0表示斜率K<1,即每次x方向+1
if (dx < dy) {
yy = 1;
swap(&x1, &y1);//将45~90度转换成0~45度
swap(&x2, &y2);
swap(&dx, &dy);
}
int ix = (x2 - x1) > 0 ? 1 : -1,
iy = (y2 - y1) > 0 ? 1 : -1,
cx = x1,
cy = y1,
d1 = dy << 1,
vd2 = - dx << 1, //d2 =(dy - dx)*2,而d+=d2相当于d-=vd2
d = - dx;
while (cx != x2) {
d += d1;
if (d>0) {
cy += iy;
d += vd2;
}
if(yy) // if k > 1
pDC->SetPixel(cy,cx,RGB(0,255,0));
else
pDC->SetPixel(cx,cy,RGB(0,255,0));
cx += ix;
}
}
- 2012.10.11 周四
- 2014.09.11 周四-jdbc
- 2016-11-3 周四
- 周四
- 2014/11/20周四例会会议
- 周四007欧联杯 佛罗伦萨 VS 门兴[11]
- 2014年12月11日下午——周四
- ACM-11月2日周四周中训练心得
- ACM-11月9日周四周中训练心得
- ACM-11月16日周四周中训练心得
- ACM-11月23日周四周中训练心得
- ACM-11月30日周四周中训练心得
- 0515周四
- 0529周四
- 0529周四
- 0605周四
- 0605周四
- 0821周四
- c++反汇编代码分析--偷调函数
- c++反汇编代码分析--循环结构
- C++反汇编代码分析--函数调用
- arm-linux-gcc 常用参数讲解 gcc编译器使用方法
- 在XSLT中对for-each语句使用distinct操作
- 2012.10.11 周四
- 获取网卡MAC地址
- hdu 2829 Lawrence 四边形优化 dp
- C++面试题:介绍一下STL,STL如何实现vector
- 准备用CSDN博客记录我程序员生涯的点滴历程
- Nlog for silverlight4
- 将一个DataTable中的DataRow插入另一个DataTable
- Jquery AJAX 请求IE缓存,数据不更新的问题
- Eclipse插件开发之基础篇(2) 第一个Eclipse插件