Antialiasing 反混淆算法 反走样算法

反走样算法有很多种.先就<<Introduction to Computer Graphics>>中的Unweighted Area Sampling(不加权采样)和Weighted Area Sampling(加权采样)做一下讨论:

                       Antialiasing

   The primitives drawn using the algorithms studied before have a common problem. They have jagged edges. This undesirable effect, known as the jaggies, or staircasing, is the result of an all-or-nothing approach to scan conversion in which each pixel either is replaced with the primitive's color or is left unchanged. Jaggies are an instance of a phenomenon known as aliasing. The application of techniques that reduce or eliminate aliasing is referred to as antialiasing .

 

Unweighted Area Sampling

The first approach to improving picture quality can be developed by recognizing that although an ideal primitive such as the line has zero width, the primitive that is being drawn has nonzero width as shown below:

The technique of setting intensity proportional to the amount of area covered is called unweighted area sampling.

Weighted Area Sampling

In weighted area sampling, we keep unweighted area sampling's first and second properties (intensity decreases with decreased area overlap, and primitives contribute only if they overlap the area represented by the pixel), but we alter the third property. We let equal areas contribute unequally: A small area closer to the pixel center has greater influence than does one at a greater distance.

To retain the second property, we must make the following change in the geometry of the pixel. In unweighted area sampling, if the edge of a primitive is quite close to the boundary of the square tile we have used to represent a pixel until now, but does not actually intersect this boundary, it will not contribute to the pixel's intensity. In the new approach, the pixel represents a circular area larger than the square tile; the primitive will intersect this larger area; hence, it will contribute to the intensity of the pixel.

对于Unweighted Area Sampling实现的算法如下,但应该注意的是在取直线经过点所占面积时应是通过计算周围一定范围内点的面积确定的(如一个正方形),确定好一个点的灰度然后继续下去直到绘完整条线.附代码如下 :

//判断某个点是否在直线矩形区域内
 

bool   CGraphicsView::  Check(int x0,int y0, float k ,float d, float x, float y)
{
  //float dy = y1 - y0,dx = x1 - x0;
  //float d = 0.5 * sqrt(dx*dx + dy*dy)/dx;//在坐标x固定时直线的宽度
   
  
  float yp = (x - x0)*k + y0;
 if( y < yp + d && y > yp - d)
  return true;
 return false;
}
//取得某一个点的灰度

float CGraphicsView::GetColorDepth(int x0,int y0,float k ,float p, int x, int y)
{
 
 float d = 0.01f;
 float length = 1/d - 2;
 int num = 0;
 for (int i = 1;i < length;i++)
 {
  for (int j = 1;j < length;j++)
  {
   if(Check(x0,y0,k,   p, x + d*i, y + d*j))
    num++;
  }
 }//取得直线过一个正方形的像素点集的个数(面积)
 float rate = num/(length * length);//由此我们确定出像素面积
 return rate;

}

void CGraphicsView::AntiAliasLine (int x0, int y0, int x1, int y1)
{
 float dy = y1 - y0,dx = x1 - x0;
   float d = 0.5 * sqrt(dx*dx + dy*dy)/dx;//在坐标x固定时直线的宽度
    float k=dy/dx;
  
 // float yp = (x - x0)*dy/dx + y0;
  for (int x = x0;x <= x1;x++)
  {
   for(int y = y0;y <= y1;y++)
   {
    //计算点的灰度值
   
 float colorDepth = GetColorDepth( x0, y0,k,d,x,y);
 
 
glBegin(GL_POINTS); //画一个点
glColor3f(colorDepth ,colorDepth ,colorDepth );
glVertex2d(x,y); 
glEnd();

   }
  }
 
}

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值