计算机图形学复习要点
1. 计算机图形学概念
- 计算机图形学是研究怎样利用计算机来显示、生成和处理图形的原理、方法和技术的学科
- ISO定义为:图形学是研究通过计算机将数据转化为图形,并在专门显示设备上显示的原理、方法和技术
- IEEE定义为:图形学是利用计算机产生图形化的图像的艺术和科学
2. 图形显卡显示原理
- 显示处理器 -》显示处理器存储器–帧缓存-》显示控制器 -》显示器
3. 液晶显示器的原理
- 液晶是一种介于固体和液体之间的一种特殊物质
- 液晶显示器通过利用液晶的光电效应,通过改变电压来改变液晶的光学特性,达到显示不同图像的目的
4. CRT工作原理
- 电子枪发射电子束,经过聚焦系统、加速电极、偏转系统,轰击到荧光屏的不同部位,被其内表面的荧光物质吸收,发光产生可见的图形
5. 填充算法
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)