Advertisement

计算机图形学代码

阅读量:

DDA生成直线算法:void DDALine(int x₀,int y₀,int x₁,int y₁,int color)

{int i;float dx,dy,length,x,y;

if(fabs(x₁ -x₀)>=fabs(y₁ -y₀))

length=fabs(x₁-x₀);

else

length=fabs(y₁-y₀);

dx = (x₁-x₀)/length; dy=(y₁-y₀)/length;

i = 1 ;x = x ₀;y= Yo;

while(i<=length)

{SetPixel ( int(x+0.5),int(y+0.5),color);

x=x+ dx;y=y+dy;i + + ;}〕

Bresenham画线算法:(0<k<1)

void Bresenham_Line( int x₀, int y₀, int x₁, int y₁, int color)

{int dx,dy,e,i,x,y;

dx = x₁ -x₀,dy = y₁ - y₀,e=2*dy-dx;

x = x₀,y= y₀;

for ( i= 0;i < =dx;i++)

{SetPixel(x,y,color); x++ ;

if ( e>= 0)

{y++ ;e=e+2dy-2dx;}else

e=e+2*dy;}}

中点画圆法:MidPointCircle(int r,int color)

{int x,y;int e;x = 0;y = r;e = 1 - r;

CirclePoints(x,y,color);

while( x < = y)

{if( e< 0)

e+ =2 * x + 3;

else

{e+= 2 * ( x- y) + 5; y -- ;

} x++ ;

CirclePoints(x,y,color);}}

四连通:(内点表示)

void FloodFill4(int x,int y,int oldcolor,int newcolor)

{if(GetPixel(x,y)==oldcolor)

{SetPixel(x,y,newcolor);

FloodFill4(x,y+1,oldcolor,newcolor);

FloodFill4(x,y-1,oldcolor,newcolor);

FloodFill4(x-1,y,oldcolor,newcolor);

FloodFill4(x+1,y,oldcolor,newcolor);}}

(边界表示)

void BoundaryFill4(int x,int y,int boundarycolor,int newcolor)

{int color=GetPixel(x,y);

if(color!=newcolor &&color!=boundarycolor)

{SetPixel(x,y,newcolor);

BoundaryFill4(x,y+1,boundarycolor,newcolor);

BoundaryFill4(x,y-1,boundarycolor,newcolor);

BoundaryFill4(x-1,y,boundarycolor,newcolor);

BoundaryFill4(x+1,y,boundarycolor,newcolor);}}

边表:void polyfill(polygon,color)

int color;

多边形polygon;

{for(各条扫描线,标识为i)

{初始化新边表头指针 NET[i];

把ymin=1的边放进边表NET[i];}

y= 最低扫描线号;

初始化活性边表AET为空;

for(各条扫描线i) {
将新生成的边表NET[i]中的所有边节点按照插入排序的方法整合进AET表格中,并确保这些节点按照x坐标递增顺序排列;
依次访问并处理AET表格中的各个节点:
对于配对交点区间(左闭右开区间)内的像素(x, y),使用drawpixel(x, y, color)函数更新其颜色值;
移除所有y坐标为1的节点,并对那些y坐标大于当前扫描线i的所有节点进行x坐标的增量处理Δx;
如果允许多边形边界自相交的情况,则采用冒泡排序算法重新排列整个AET表格以确保数据的一致性与完整性;
}

边界标志算法:void edgemark_fill(polydef,color)

多边形定义 polydef; int color;

{对多边形polydef每条边进行直线扫描转换;inside = FALSE;

for(每条与多边形polydef相交的扫描线y)

for(扫描线上每个像素x)

{if(像素x被打上边标志)

inside =! (inside);

if(inside!= FALSE)

drawpixel(x, y,color);

else drawpixel(x, y,background);}}​

扫描线种子填充算法:typedef struct{

int x; int y;

}Seed;

void ScanLineFil14(int x,int y,COLORREF oldcolor,COLORREF newcolor)

{int x1,xr,i;

bool spanNeedFill;

Seed pt;

setstackempty();

pt.x=x; pt.y=y;

stackpush(pt);

while(! isstackempty())

{pt = stackpop();y=pt.y;x= pt.x;

while(getpixel(x,y)==oldcolor)

{SetPixel(x,y,newcolor);x++;}

xr=x-1; x=pt.x-1;

while(getpixel(x,y)==oldcolor)

{ SetPixel(x,y,newcolor);x--;}

x1=x+1;x=x1;y=y+1;

while(x<xr)

{spanNeedFill = FALSE;

while(getpixel(x,y)==oldcolor)

{spanNeedF i11 = TRUE;x++;}

if(spanNeedFill)

{ pt.x=x-1;pt.y=y;stackpush(pt);

spanNeedFi11 = FALSE;

}while(getpixel(x,y)!=oldcolor && x<xr) x++;

}x=x1;y=y-2;while(x<xr){spanNeedFi11 = FALSE;

while(getpixel(x,y)==oldcolor)

{spanNeedFill = TRUE;

x++;}if(spanNeedFil1)

{pt.x=x-1;pt.y=y;

stackpush(pt);

spanNeedFil1=FALSE;}while(getpixel(x,y)!=oldcolor && x<xr) x++;}}}

Z缓冲器消隐算法:

帧缓冲区置成背景色;

Z缓冲区置成某初始值,该值比场景在观察坐标系下的最小z值还小;

for(各个多边形)

{扫描转换该多边形;

for(多边形所覆盖的每个像素(x,y))

{计算该像素所对应多边形上的点在观察坐标系下的z坐标值Z(x,y);

if(Z(x,y)大于Z缓冲区在(x,y)处的值)

{Z缓冲区中(x,y)处深度值替换为Z(x,y);

帧缓冲区中(x,y)处亮度值替换为多边形在(x,y)处的亮度值;}}}

光线跟踪:

DrawImage()

{for(帧缓冲区中的每一个像素e)

计算像素e在投影平面上对应的点e';然后由视点V射出一条光线指向e',其方向定义为direction。

Ray-Tracing(e',direction,1.0,1,&I);

将像素e的颜色设置为 (Ir,Ig,Ib);}}

Ray-Tracing(startPoint,direction,weight,depth,I)

if(( depth>TREE_MAX_DEPTH)||( weight<CONTRIBUTE_COEFFICIENT_THRESHOLD))

{*I= 0; return;}

计算从起点startPoint出发、沿指定方向direction延伸并穿过场景内各物体表面时的所有可能路径;若有相交结果,则记录离起点startPoint最近的那个交点P₁,并进一步计算该交点处光线在物表上的反射方向向量及透射方向向量分别设为direction_r和direction_t。同时将该物体表面镜面反射系数及透射系数分别设为K_sK_t

if(无交点)

{*I=0;return;}

else

基于简单光照模型进行计算,在光源直接照射下导致(-1×direction)方向上的反射光强为Ic。

Ray-Tracing(P₁, direction_r, weight*Ks,depth+ 1,&Is);

Ray-Tracing(P₁, direction_t, weight*Kt,depth+1,&It);

*I=Ic+Ks·Is+Kt·It

return;}}

曲线的De Casteljau算法:

float Casteljau( int k, float controlsa[], float t)

{int r,i; float t1, contolsa[10]; t1=1.0-t;

for(i=0;i<=k,;i++)

controlsa[]=controls[i];

for(r=1:r<=k ;i++) for(i=0; i<= k-r;i++)

controlsa[i]=t1controlsa[i]+tcontrolsa[i];

return controlsa[0];)

void bezier_to_points(int k,int npoints,float controls[], float points[])

{float t, delt; int i;

delt=1.0/(float)npoints;

t=0.0;

for(i=0;i<=points;i++)

points=Casteljau( k, controls,t)

t=t + delt;}

曲面的De Casteljau算法:

DeCasteljauSurf(P, n, m, u, v, S)

{ if(n<=m)

{ for(j=0;j<=m;j++)

DeCasteljau(P[j][], n, u, Q[j])

DeCasteljau(Q, m, v, S) ; }

else {for(i=0;i<=n;i++)

DeCasteljau(P[][i], m, v, Q[i]) ;

DeCasteljau(Q, n, u, S) ; }

光线跟踪算法:

设置视点,投影平面以及窗口的参数;

For (窗口内的每一条扫描线)

for (扫描线上的每一个像素)

{ 确定从视点指向像素中心的光线ray;

像素的颜色=RayTracing(ray,1);}

Color RayTracing(Ray ray, int depth)

{ 求ray与物体表面最近的交点P;

if (有交点)

{ 用局部光照明模型计算P点的Ic;

color = Ic;

if (depth<给定的最大跟踪层次)

{ 计算ray的反射光线;

Is=RayTracing(反射光线,depth+1);

if (物体是透明的)

{ 计算ray的透射光线;

It=RayTracing(透射光线,depth+1); }

color = Ic + Is + It ; } else color = black;

return color ;}

全部评论 (0)

还没有任何评论哟~