算法是在隐面的基础上,加上了颜色双线性插值.
{1}隐面:使用透视投影,即有(phi,theta,R),再用<37 立方体动态隐线算法>,即如果视向量S(视点E与平面上任意一点组成的向量P1:P1E)与法向量N(可由面上三个点P1P2P3组成,P1P2*P2P3)求数量积S.N >= 0,则绘制该面;否则表示人看不到该面,故要隐藏该面.
(2)颜色插值类似于Z-Buffer隐面算法,对每个面,每条扫描线,每次找2个点,设置像素颜色为双线性插值颜色.
(3)有效边定义多了个线段的2个端点及颜色,以便进行插值:
E[i].x=Point[j].x;//上面点的x值
E[i].yMax=Point[i].y;//下面点的y值
E[i].k=double((Point[i].x-Point[j].x))/(Point[i].y-Point[j].y);
E[i].x1=Point[i].x;//保存第一个端点坐标及颜色
E[i].y1=Point[i].y;
E[i].c1=Point[i].c;
E[i].x2=Point[j].x; //保存第2个端点坐标及颜色
E[i].y2=Point[j].y;
E[i].c2=Point[j].c;
(4)颜色双线性插值代码如下:
Is=Interpolation(CurrentB->ScanLine,HeadE->y1,HeadE->y2,HeadE->c1,HeadE->c2);
It=Interpolation(CurrentB->ScanLine,HeadE->next->y2,HeadE->next->y1,HeadE->next->c2,HeadE->next->c1);
}
BOOL In=false;//设置一个BOOL变量In,初始值为假
int xb,xe;//扫描线区间的起点和终点
for(T1=HeadE;T1!=NULL;T1=T1->next)//填充扫描线和多边形相交的区间
{
if(In==false)
{
xb=ROUND(T1->x)-1;
In=true;//每访问一个结点,把In值取反一次
}
else//如果In值为真,则填充从当前结点的x值开始到下一结点的x值结束的区间
{
xe=ROUND(T1->x);
for(double x=xb;x<=xe;x++)
{
Ip=Interpolation(ROUND(x),xb,xe,Is,It);
mdc->SetPixel(MaxX/2+ROUND(x),MaxY/2+CurrentB->ScanLine,RGB((BYTE)(Ip.red*255),(BYTE)(Ip.green*255),(BYTE)(Ip.blue*255)));
}
In=false;
}
}