计算机图形学复习

计算机图形学复习要点

1. 计算机图形学概念

  • 计算机图形学是研究怎样利用计算机来显示、生成和处理图形的原理、方法和技术的学科
  • ISO定义为:图形学是研究通过计算机将数据转化为图形,并在专门显示设备上显示的原理、方法和技术
  • IEEE定义为:图形学是利用计算机产生图形化的图像的艺术和科学

2. 图形显卡显示原理

  • 显示处理器 -》显示处理器存储器–帧缓存-》显示控制器 -》显示器

3. 液晶显示器的原理

  • 液晶是一种介于固体和液体之间的一种特殊物质
  • 液晶显示器通过利用液晶的光电效应,通过改变电压来改变液晶的光学特性,达到显示不同图像的目的

4. CRT工作原理

  • 电子枪发射电子束,经过聚焦系统、加速电极、偏转系统,轰击到荧光屏的不同部位,被其内表面的荧光物质吸收,发光产生可见的图形

5. 填充算法

  • 边缘填充算法
  • 区域填充
  • x-扫描线填充

6. 反走样

  • 走样
    • 用离散量表示连续量引起的失真现象称为走样
    • 阶梯状边界
    • 图形细节失真
  • 反走样
    • 减少或者消除这种效果的技术
    • 提高分辨率
    • 区域采样
    • 加权区域采样

7.Bezier曲线性质

  • 端点性质
  • 对称性
  • 凸包性
  • 几何不变性

8.B样条曲线性质

  • 端点性质和连续性
  • 局部性
  • 扩展性

矩形旋转算法

/**
 * ctx:画布上下文
 * rect:矩形
 * n:旋转的次数
 * delta:旋转的角度
 */
function drawRotateRect(ctx, rect, n, delta) {
    //判断画出的矩形是否存在
   if (rect.width <= 0 || rect.height <= 0) return;
    /**
     * xm:画出的矩形的中心x坐标
     * ym:画出的矩形的中心y坐标
     * sinAF:旋转角的sin
     * cosAF:旋转角的cos
     *
     */
   var xm, ym, sinAF, cosAF, s, tx, ty;
   delta *= Math.PI / 180;
   sinAF = Math.sin(delta);
   cosAF = Math.cos(delta);
   xm = rect.x0 + rect.width/2;
   ym = rect.y0 + rect.height/2;
   s = 1 / (sinAF + cosAF);

   var pts = new Array(4);
   pts[0] = new Point2(rect.x0, rect.y0);
   pts[1] = new Point2(rect.x0, rect.y0+rect.height);
   pts[2] = new Point2(rect.x0+rect.width, rect.y0+rect.height);
   pts[3] = new Point2(rect.x0+rect.width, rect.y0);
   for (var i=0; i<n; i++) {
      for (var j=0; j<4; j++) {
         drawLine_Bresenham(ctx, Math.round(pts[j].x), Math.round(pts[j].y),
                        Math.round(pts[(j+1)%4].x), Math.round(pts[(j+1)%4].y));
      }
      for(var j=0; j<4; j++) {
            //(1)平移到矩形中心
            pts[j].x -= xm;
            pts[j].y -= ym;
            //(2)旋转角度delt
            tx = cosAF*pts[j].x - sinAF*pts[j].y;
            ty = sinAF*pts[j].x + cosAF*pts[j].y;
            pts[j].x = tx;   pts[j].y = ty;
            //(3)缩放
            pts[j].x *= s;
            pts[j].y *= s;
            //(4)反平移
            pts[j].x += xm;
            pts[j].y += ym;
        }
   }
}

编码裁剪算法

function getClipCode(pt, win)
{
    var code = 0;
    
    if(pt.y > win.bottom()) code |= 0x01;
    else if(pt.y < win.top()) code |= 0x02;
    
    if(pt.x > win.right()) code |= 0x04;
    else if(pt.x < win.left()) code |= 0x08;
    
    return code;
}

function lineClip(line, win)
{
    var c, c0, c1;
    var pt, pt0, pt1;
   
   pt0 = line.start.copy();
   pt1 = line.end.copy();
   
    while(true)
    {
        c0 = getClipCode(pt0, win);
        c1 = getClipCode(pt1, win);
        if((c0 & c1) != 0) return null;
        
        if(c0 == 0 && c1 == 0) 
      {
         pt0.x = Math.round(pt0.x);
         pt0.y = Math.round(pt0.y);
         pt1.x = Math.round(pt1.x);
         pt1.y = Math.round(pt1.y);
         return new Line2(pt0, pt1);
      }
        
        if(c0 == 0)
        {
         [pt0, pt1] = [pt1, pt0];
         [c0, c1] = [c1, c0];
        }
        
        if(c0 & 0x01)   // 在Yb之下
        {
            pt0.x = pt0.x-(pt0.y-win.bottom())*(pt0.x-pt1.x)/(pt0.y-pt1.y);
            pt0.y = win.bottom();
        }
        else if(c0 & 0x02) // 在Yt之上
        {
            pt0.x = pt0.x-(pt0.y-win.top())*(pt0.x-pt1.x)/(pt0.y-pt1.y);
            pt0.y = win.top();
        } 
        else if(c0 & 0x04) // 在Xr之右
        {
            pt0.y = pt0.y-(pt0.x-win.right())*(pt0.y-pt1.y)/(pt0.x-pt1.x);
            pt0.x = win.right();
        }
        else if(c0 & 0x08) // 在Xl之左
        {
            pt0.y = pt0.y-(pt0.x-win.left())*(pt0.y-pt1.y)/(pt0.x-pt1.x);
            pt0.x = win.left();
        } 
    }
}

三次B样条曲线算法

void cubicBSplineBase(int begin,const GPoint2dArray &points,double t,GPoint2d &pt){
    float fh1 = (-t*t*t*t+3*t*t-3*t+1)/6;
    float fh2 = (3*t*t*t-6*t*t)/6;
    float fh3 = (-3*t*t*t+3*t*t+3*t+1)/6;
    float fh4 = (t*t*t)/6;
    GPoint2d pt0 = points.at(begin);
    GPoint2d pt1 = points.at(begin+1);
    GPoint2d pt2 = points.at(begin+2);
    GPoint2d pt3 = points.at(begin+3);
    pt.setX(fh1*pt0.x()+fh2*pt1.x()+fh3*pt2.x()+fh4*pt3.x())
    pt.setY(fh1*pt0.y()+fh2*pt1.y()+fh3*pt2.y()+fh4*pt3.y())
}
void gltBSpline2d(const GPoint2dArray &points){
    if(points.count()<4)return;

    double x0,y0;
    double t,dt;
    GPoint2d pt;
    
    int n = points.count();
    dt = 0.05;

    for (int i = 0; i < n-3; i++)
    {
        cubicBSplineBase(i,points,0,pt);
        x0 = pt.x();
        y0 = pt.y();
        for (t=d; t < 1; t+=dt)
        {
            cubicBSplineBase(i,points,0,pt);
            gltLine2d(x0,y0,pt.x(),pt.y()); 
            x0 = pt.x();
            y0 = pt.y();
            
        }
        
    }
    
}

贝塞尔曲线算法

double bezierCastel(double x[],int n ,double t){
    for (int r = 0; r < n; r++)
    {
        for (int i = 0; i < n-r; i++)
        {
            x[i] = (1-t)*x[i]+t*x[i+1];
        }
        
    }
    return x[0];
    
}

void gltBezier2d(const GPoint2dArray &points){
    if (points.count()<2)return;

    double x0,y0,x1,y1;
    double t,dt;
    GPoint2d pt;
    int n = points.count();
    dt = 1.0f/(n*20);
    double *x = new double[n];
    double *y = new double[n];

    pt = points.at(0);
    x0 = pt.x();
    y0 = pt.y();

    for (int i = 0; i < n; i++)
    {
        pt = points.at(i);
        x[i] = pt.x();
        y[i] = pt.y();
    }

    for ( t=dt; t<1; t+=dt)
    {
        x1 = bezierCastel(x,n,t);
        y1 = bezierCastel(x,n,t);
        gltLine2d(x0,y0,x1,y1);
        x0 = x1;
        y0 = y1;

    }

    pt = points.at(i);
    gltLine2d(x0,y0,pt.x(),pt.y());
    
    delete []x;
    delete []y;
}

OpenGL相关函数

  • 视点变换函数-----GluLookAt(double eyeX,eyeY,eyeZ,centerX,centerY,centerZ,upX,upY,upZ)
  • 平行投影函数-----glOrtho(double left ,right,bottom,top,near,far)
  • 开启多边形消影处理----glEnable(GL_CULL_FACE) ------glCullFace(mode)
  • 开启光照----glEnable(GL_LIGHTING)-----glEnable(light)
  • 开启纹理贴图-----glEnable(GL_TEXTURE_2D)
上一篇:凸包模板


下一篇:目标检测中焦点损失的原理