用于520的20年前的图片

今天是520,20年前肯定没有这个“节日”呢。下面是20年前的一张图,当时用于送给Dudu的生日礼物哦:

Hss:来看看我给你做的生日贺卡。

Dudu:啊,好漂亮,你怎么实现的?

Hss:啊,是这样,在背景放上文字和心形,中间放三个玻璃球,然后指定光源位置,用光线跟踪算法来做光线渲染,然后……

然后,然后就没有然后了。

上图是1996年(20年前)选修了学校的”计算机图形学“课程,其中一个作业是实现光线追踪算法,然后就有了上面的完成的作业。作业的代码原始版本是从师兄那里获得(但原始作者不清楚是不是师兄), 我在原有代码上进行了少许修改,包括:

(1)光线跟踪作业里加入了心形的背景,以及人名的缩写

(2)纹理作业里加入了随机性,用于模拟树木的年轮

恩,其实就是抄作业啦,惭愧!

代码附后(源代码是Turbo C 2.0的工程,这里只是主要源代码):

/****************************************************************************
  我在1996(20年前)年选修学校的计算机图像学课程,课后作业是编程实现一些课上学习的算法

  此代码原始版本是从师兄那里获得(但原始作者不清楚是不是师兄)

  我在原有代码上进行了少许修改,包括:

  (1)光线跟踪作业里加入了心形的背景,以及人名的缩写

  (2)纹理作业里加入了随机性,用于模拟树木的年轮

  Tom Huang 于 2016/5/20 补记

\*******************************************************************************/

#include <windows.h>
#include <stdio.h>
#include <math.h>
#include "cge.h"
#include "lut.h"

#define   ERROR               0.1E-6
#define   line1(p)      ((p1[0]-p0[0]) * (p[1]-p0[1]) - (p1[1]-p0[1]) * (p[0]-p0[0]))

typedef struct tagRGB
    {
    unsigned int red , green , blue;
    }RGB,*PRGB;

void CGEWork0(HDC hDC)
    {
    int i;
    int j;
    SetLUT(hDC);
    for(j=0;j<256;j++)
        for(i=0;i<100;i++)
            {
            SetPixel(hDC,2*j,i,(0x01000000L |j));
            SetPixel(hDC,2*j+1,i,(0x01000000L | j));
            }
    }

void ShapeSphere(hDC,kd,ks,n,Xcenter,Ycenter,R)
HDC hDC;
double ks,kd,Xcenter,Ycenter,R;
int n;

{
int Ilight,Ir,Ig,Ib,Ia;
double Hx,Hy,Hz,Lx,Ly,Lz,xn,yn,zn,LN,NHn,NH;
double Id,Is,x,y,z,Ka;
Ilight = 120;
Ia =320;
Ka = 0.2;
Lx=Ly=Lz=0.57735;
Hx = 0.325058;
Hy = 0.325058;
Hz = 0.888075;
SetLUT_GREEN(hDC);
for(y = (-R);y <= R ; y++)
    for( x = (-R);x <= R;x++ )
        {
        if (x*x+y*y <= R*R)
            {
            z=sqrt(R*R-x*x-y*y);
            xn=x/R;
            yn=y/R;
            zn=z/R;
            LN=xn*Lx+yn*Ly+zn*Lz;
            if(LN>0)
                {
                NH=Hx*xn+Hy*yn+Hz*zn;
                NHn=pow(NH,n);
                }
            if(LN<0)
                {
                Ig=Ia*Ka;
                Ir=Ib=0.0;
                }
            else
                {
                Id=kd*LN*Ilight;
                Is=ks*NHn*Ilight;
                Ig=(Ka*Ia+Id+Is);
                Ir=Ib=0;
                }
            SetPixel(hDC,Xcenter+x,Ycenter+y,PALETTERGB(Ir, Ig, Ib));
            }
        }
}

//Phong
void CGEWork1(HDC hDC)
{
double Kd,Ks,r,X,Y;
int i,j;
int n;
Kd = 0;
n = 5;
r = 25.0;
Y=50;
for(i=1;i<=4;i++)
    {
    Kd=0;
    Ks = 1- Kd;
    X=100;
    for(j=1;j<=5;j++)
        {
        ShapeSphere(hDC,Kd,Ks,n,X,Y,r);
        Kd += 0.25;
        Ks = 1-Kd;
        X+=60;
        }
        Y+=60;
        n *= 2;
    }

}

//Cook
void CGEWork2(HDC hDC)
    {
    int Xcenter,Ycenter;
    double f,dw,s,d,m,tmp,G0,Gm,Gs,D,G,NV,NH,NL,VH,HL;
    double x,y,z,xn,yn,zn,Lxn,Lyn,Lzn;
    double Vx,Vy,Vz,Hxn,Hyn,Hzn,Lx,Ly,Lz,Hx,Hy,Hz;
    double nr,ng,nb,For,Fog,Fob,Rdr,Rdb,Rdg,Rsr,Rsb,Rsg;
    double Rar,Rag,Rab,Fr,Fb,Fg,o,or,ob,og;
    double PI,R;
    unsigned long Ir,Ig,Ib,Ip,Ia;

    PI=3.14159265;
    Ip=600000L;
    R=100.0;
    Xcenter=200;
    Ycenter=150;
    f=1.0;
    dw=0.0002;
    s=0.9;
    d=0.1;
    m=0.3;

    Rdr=For=0.755;
    Rdb=Fob=0.095;
    Rdg=Fog=0.490;

    Ia=0.00006*Ip;

    Lx =-5.0;
    Ly=-5;
    Lz=10.0;
    Vx = 0.0;
    Vy = 0.0;
    Vz = 1.0;
    Rar=PI*Rdr;
    Rag=PI*Rdg;
    Rab=PI*Rdb;
    nr=(1+sqrt(For))/(1-sqrt(For));
    ng=(1+sqrt(Fog))/(1-sqrt(Fog));
    nb=(1+sqrt(Fob))/(1-sqrt(Fob));
    tmp=sqrt(Lx*Lx+Ly*Ly+Lz*Lz);
    Lxn=Lx/tmp;
    Lyn=Ly/tmp;
    Lzn=Lz/tmp;
    Hx=(Lx+Vx)/2;  //?
    Hy=(Ly+Vy)/2;  //?
    Hz=(Lz+Vz)/2;  //?
    tmp=sqrt(Hx*Hx+Hy*Hy+Hz*Hz);
    Hxn=Hx/tmp;
    Hyn=Hy/tmp;
    Hzn=Hz/tmp;
    VH=Vx*Hxn+Vy*Hyn+Vz*Hzn;
    SetLUT_YELLOW(hDC);
    for (y=(-R);y<=R;y++)
        for (x=(-R);x<=R;x++)
            {
            if (x*x+y*y<=R*R)
                {
                z=sqrt(R*R-x*x-y*y);
                xn=x/R;
                yn=y/R;
                zn=z/R;
                NL=xn*Lxn+yn*Lyn+zn*Lzn;
                NV=xn*Vx+yn*Vy+zn*Vz;
                NH=xn*Hxn+yn*Hyn+zn*Hzn;
                G0 = 1.0;
                if((NL>0)&&(NV>0)&&(NH>0))
                    {
                    Gs=2.0*NH*NL/VH;
                    Gm=2.0*NH*NV/VH;
                    G=min(G0,Gs);
                    G=min(G ,Gm);
                    o = acos(NH);
                    D=(exp(-pow(tan(o),2)/(m*m)))/(m*m*pow(NH,4));
                    HL=(Lxn*Hxn+Lyn*Hyn+Lzn*Hzn);
                    o=acos(HL);
                    or=asin(sin(o)/nr);
                    Fr=0.5*(pow(sin(o-or),2)/pow(sin(o+or),2)
                      +pow(tan(o-or),2)/pow(tan(o+or),2));
                    Rsr=Fr*D*G/(NV*NL*PI);
                    og=asin(sin(o)/ng);
                    Fg=0.5*(pow(sin(o-og),2)/pow(sin(o+og),2)
                      +pow(tan(o-og),2)/pow(tan(o+og),2));
                    Rsg=Fg*D*G/(NV*NL*PI);
                    ob=asin(sin(o)/nb);
                    Fb=0.5*(pow(sin(o-ob),2)/pow(sin(o+ob),2)
                      +pow(tan(o-ob),2)/pow(tan(o+ob),2));
                    Rsb=Fb*D*G/(NV*NL*PI);
                    Ir=Ia*Rar*f+Ip*NL*dw*(s*Rsr+d*Rdr);
                    Ib=Ia*Rab*f+Ip*NL*dw*(s*Rsb+d*Rdb);
                    Ig=Ia*Rag*f+Ip*NL*dw*(s*Rsg+d*Rdg);
                    if (Ir>255)
                        Ir = 255;
                    if (Ig>255)
                        Ig = 255;
                    if (Ib>255)
                        Ib = 255;
                    }
                else
                    {
                    Ir=Ia*Rar*f;
                    Ig=Ia*Rag*f;
                    Ib=Ia*Rab*f;
                    }
               SetPixel(hDC,Xcenter+x,Ycenter+y,PALETTERGB(Ir,Ig,Ib));
               }
            }
    }

double square(double a,double b,double c)
        {
        double m;
        m = sqrt(a*a+b*b+c*c);
        return m;
        }

//gourand
void CGEWork3(HDC hDC)
    {
    double PointX[11],PointY[11],PointZ[11];
    double R,High,temp1,temp2,temp3,length;
    double I[11];
    double t,Ax,Ay,Az,Bx,By,Bz,Cx,Cy,Cz,Dx,Dy,Dz;
    double Vx,Vy,Vz,Lx,Ly,Lz,Lxn,Lyn,Lzn;
    double x0,x1,y0,y1,LNN,NHn,NH;
    int    Xcenter,Ycenter,i,j;
    float  Kd,Ks;
    long   Ilight,Iaka,Ir,Ib,Ig,Id,Is;

    t = sqrt(3.0);
    Ax=0.0; Ay=(-t)/2.0; Az=0.5;
    Bx=(-t)/2.0; By=0.25; Bz=(t)/4.0;
    Cx=0; Cy=0.5; Cz=t/2.0;
    Dx=(t)/2.0; Dy=0.25; Dz=(t)/4.0;
    Vx=0; Vy=0; Vz=1.0;
    Lx=(Ax+Cx+Bx)/3.0;
    Ly=(Ay+Cy+By)/3.0;
    Lz=(Az+Cz+Bz)/3.0;
    Lxn=Lx/sqrt(Lx*Lx+Ly*Ly+Lz*Lz);
    Lyn=Ly/sqrt(Lx*Lx+Ly*Ly+Lz*Lz);
    Lzn=Lz/sqrt(Lx*Lx+Ly*Ly+Lz*Lz);
    Kd = 0.2;
    Ks = 0.7;
    Ilight = 200;
    Iaka = 50;
    R=40;
    High= 150;
    length=square((Ax-Cx-Dx),(Ay-Cy-Dy),(Az-Cz-Dz));
    PointX[1]=(Ax-Cx-Dx)/(length);
    PointY[1]=(Ay-Cy-Dy)/(length);
    PointZ[1]=(Az-Cz-Dz)/(length);
    length=square((Ax-Cx-Bx),(Ay-Cy-By),(Az-Cz-Bz));
    PointX[2]=(Ax-Cx-Bx)/(length);
    PointY[2]=(Ay-Cy-By)/(length);
    PointZ[2]=(Az-Cz-Bz)/(length);
    length = square((Ax+Bx-Dx),(Ay+By-Dy),(Az+Bz-Dz));
    PointX[3]=(Ax+Bx-Dx)/(length);
    PointY[3]=(Ay+By-Dy)/(length);
    PointZ[3]=(Az+Bz-Dz)/(length);
    length = square((Ax+Dx-Bx),(Ay-By+Dy),(Az-Bz+Dz));
    PointX[4]=(Ax+Dx-Bx)/length;
    PointY[4]=(Ay-By+Dy)/length;
    PointZ[4]=(Az-Bz+Dz)/length;
    PointX[5]=Lx;PointY[5]=Ly;PointZ[5]=Lz;
    length=square((Ax+Cx+Dx),(Ay+Cy+Dy),(Az+Cz+Dz));
    PointX[6]=(Ax+Cx+Dx)/length;
    PointY[6]=(Ay+Cy+Dy)/length;
    PointZ[6]=(Az+Cz+Dz)/length;
    length = square((-Ax+Bx-Dx),(-Ay+By-Dy),(-Az+Bz-Dz));
    PointX[7]=(-Ax+Bx-Dx)/length;
    PointY[7]=(-Ay+By-Dy)/length;
    PointZ[7]=(-Az+Bz-Dz)/length;
    length=square((-Ax-Bx+Dx),(-Ay-By+Dy),(-Az-Bz+Dz));
    PointX[8]=(-Ax-Bx+Dx)/length;
    PointY[8]=(-Ay-By+Dy)/length;
    PointZ[8]=(-Az-Bz+Dz)/length;
    length=square((-Ax+Cx+Bx),(-Ay+Cy+By),(-Az+Cz+Bz));
    PointX[9]=(-Ax+Cx+Bx)/length;
    PointY[9]=(-Ay+Cy+By)/length;
    PointZ[9]=(-Az+Cz+Bz)/length;
    length=square((-Ax+Cx+Dx),(-Ay+Cy+Dy),(-Az+Cz+Dz));
    PointX[10]=(-Ax+Cx+Dx)/length;
    PointY[10]=(-Ay+Cy+Dy)/length;
    PointZ[10]=(-Az+Cz+Dz)/length;

    SetLUT_GRAY(hDC);
       Xcenter = 70;
       Ycenter = 50;
       y0=Ycenter-R*(t)/4;
       LNN = Ax*Lxn+Ay*Lyn+Az*Lzn;
       NH = Ax*Vx+Ay*Vy+Az*Vz;
       NHn = pow(NH,10);
       for(j=y0; j<=Ycenter; j++)
            {
            y1=2*(j-y0)/(t);
            x0=Xcenter-R/2-y1;
            x1=Xcenter+R/2+y1;
            for(i=x0;i<=x1;i++)
                {
                if(LNN<0) Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ir=Ib=Iaka+Id+Is+30;
                    }

         if(Ig>255)  Ib=Ig=Ir=255;
         SetPixel(hDC,i,j,PALETTERGB(Ir,Ig,Ib));
         SetPixel(hDC,i,2*Ycenter-j,PALETTERGB(Ir,Ig,Ib));

         }
    }

       x0 = Xcenter - R;
       y0 = High*(t)/2.0;
       LNN =Bx*Lxn+By*Lyn+Bz*Lzn;
       NH = Bx*Vx+By*Vy+Bz*Vz;
       NHn = pow(NH,10);
       for(i=0;i<=R/2;i++)
            {
            y1=i*(t)/2.0+Ycenter;
            for(j=0;j<=y0;j++)
                {
                if(LNN<0) Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ir=Ib=Iaka+Id+Is+30;
                    }
                if(Ig>250)  Ib=Ig=Ir=250;
                SetPixel(hDC,i+x0,j+y1,PALETTERGB(Ir,Ig,Ib));
                }
            }

       x0 = Xcenter - R/2;
       y1 = Ycenter + R*(t)/4.0;
       LNN =Cx*Lxn+Cy*Lyn+Cz*Lzn;
       NH = Cx*Vx+Cy*Vy+Cz*Vz;
       NHn = pow(NH,10);
       for(i=0;i<=R;i++)
            {
            for(j=0;j<=y0;j++)
                {
                if(LNN<0) Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ir=Ib=Iaka+Id+Is+30;
                    }
                if(Ig>250)  Ib=Ig=Ir=250;
                SetPixel(hDC,i+x0,j+y1,PALETTERGB(Ir,Ig,Ib));
                }
            }

       x0 = Xcenter + R/2;
       LNN =Dx*Lxn+Dy*Lyn+Dz*Lzn;
       NH = Dx*Vx+Dy*Vy+Dz*Vz;
       NHn = pow(NH,10);
       for(i=0;i<=R/2;i++)
            {
            y1 = (R/2-i)*(t)/2+Ycenter;
            for(j=0;j<=y0;j++)
                {
                if(LNN<0) Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ir=Ib=Iaka+Id+Is+30;
                    }
                if(Ig>250)  Ib=Ig=Ir=250;
                SetPixel(hDC,i+x0,j+y1,PALETTERGB(Ir,Ig,Ib));
                }
            }

    for ( i=1;i<11;i++)
        {
        LNN =PointX[i]*Lxn+PointY[i]*Lyn+PointZ[i]*Lzn;
        NH = PointX[i]*Vx+PointY[i]*Vy+PointZ[i]*Vz;
        NHn = pow(NH,10);
        if(LNN<0) I[i]= Iaka;
        else
            {
            Id  = Kd*LNN*Ilight;
            Is  = Ks*NHn*Ilight;
            I[i]= Iaka+Id+Is+30;
            }
        if(I[i]>250) I[i] = 250;
        }

    Xcenter = 230;
    Ycenter= 50;
    y0=R*(t)/4;
    temp1 = (I[3]-I[1])/y0;
    temp2 = (I[4]-I[2])/y0;
    for(j=0; j<=y0; j++)
        {
        y1=R*j/(2*y0);
        x0=Xcenter-R/2-y1;
        x1=Xcenter+R/2+y1;
        Ig = I[1]+temp1*j;
        Ir = I[2] + temp2*j;
        for(i=x0;i<=x1;i++)
            {
            temp3 = (Ir-Ig )*(i-x0)/(x1-x0);
            Ib = Ig+temp3;

            if(Ib>250)  Ib=250;
            SetPixel(hDC,i,Ycenter-y0+j,PALETTERGB(Ib,Ib,Ib));
            }
        }
     temp1 = (I[3]-I[5])/y0;
     temp2 = (I[4]-I[6])/y0;
     for(j=0; j<=y0; j++)
        {
        y1=R*(y0-j)/(2*y0);
        x0=Xcenter-R/2-y1;
        x1=Xcenter+R/2+y1;
        Ig = I[3]-temp1*j;
        Ir = I[4] - temp2*j;
        for(i=x0;i<=x1;i++)
            {
            temp3 = (Ir-Ig )*(i-x0)/(x1-x0);
            Ib = Ig+temp3;

            if(Ib>250)  Ib=250;
            SetPixel(hDC,i,j+Ycenter,PALETTERGB(Ib,Ib,Ib));
            }
        }

       x0 = Xcenter -R;
       y0 = High*(t)/2.0;
       temp1=(I[5]-I[3])*2/R; temp2 = (I[9]-I[7])*2/R;
       for(i=0;i<=R/2;i++)
            {
            y1=i*(t)/2.0+Ycenter;
            Ig = I[3] + temp1*i;
            Ir = I[7] +temp2*i;
            for(j=0;j<=y0;j++)
                {
                temp3 = (Ir-Ig)*j/y0;
                Ib = Ig+temp3;
                if(Ib>250)  Ib=250;
                SetPixel(hDC,i+x0,j+y1,PALETTERGB(Ib,Ib,Ib));
                }
            }

       x0 = Xcenter - R/2;
       y1 = Ycenter + R*(t)/4.0;
       temp1 =(I[6]-I[5])/R;
       temp2 =(I[10]-I[9])/R;
       for(i=0;i<=R;i++)
            {
            Ig = I[5] + temp1*i;
            Ir= I[9] +temp2*i;
            for(j=0;j<=y0;j++)
                {
                temp3= (Ir-Ig)*j/y0;
                Ib = Ig+temp3;
                if(Ib>250)  Ib=250;
                SetPixel(hDC,i+x0,j+y1,PALETTERGB(Ib,Ib,Ib));
                }
            }

       x0 = Xcenter + R/2;
       temp1=(I[4]-I[6])*2/R;
       temp2=(I[8]-I[10])*2/R;
       for(i=0;i<=R/2;i++)
            {
            y1 = (R/2-i)*(t)/2+Ycenter;
            Ig = I[6] + temp1*i;
            Ir= I[10]+temp2*i;
            for(j=0;j<=y0;j++)
                {
                temp3= (Ir-Ig)*j/y0;
                Ib = Ig+temp3;
                if(Ib>250)  Ib=250;
                SetPixel(hDC,i+x0,j+y1,PALETTERGB(Ib,Ib,Ib));
                }
            }

       Xcenter = 400;
       Ycenter= 50;
       y0=R*(t)/4;
       Ax=(PointX[3]-PointX[1])/y0;
       Ay=(PointY[3]-PointY[1])/y0;
       Az=(PointZ[3]-PointZ[1])/y0;

       Bx=(PointX[4]-PointX[2])/y0;
       By=(PointY[4]-PointY[2])/y0;
       Bz=(PointZ[4]-PointZ[2])/y0;
       for(j=0; j<=y0; j++)
            {
            y1=R*j/(2*y0);
            x0=Xcenter-R/2-y1;
            x1=Xcenter+R/2+y1;
            Cx=PointX[1]+Ax*j;
            Cy=PointY[1]+Ay*j;
            Cz=PointZ[1]+Az*j;
            Dx=PointX[2]+Bx*j;Dy=PointY[2]+By*j;Dz=PointZ[2]+Bz*j;

            length=square(Cx,Cy,Cz);
            Cx=Cx/length;Cy=Cy/length;Cz=Cz/length;
            length=square(Dx,Dy,Dz);
            Dx=Dx/length;Dy=Dy/length;Dz=Dz/length;

            for(i=x0;i<=x1;i++)
                {
                I[1]=Cx+(Dx-Cx)*(i-x0)/(x1-x0);
                I[2]=Cy+(Dy-Cy)*(i-x0)/(x1-x0);
                I[3]=(Dz-Cz)*(i-x0)/(x1-x0)+Cz;
                length=square(I[1],I[2],I[3]);
                I[1]=I[1]/length;
                I[2]=I[2]/length;
                I[3]=I[3]/length;
                LNN =I[1]*Lxn+I[2]*Lyn+I[3]*Lzn;
                NH  = I[1]*Vx+I[2]*Vy+I[3]*Vz;
                NHn = pow(NH,10);
                if(LNN<0) Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ib=Ir=Iaka+Id+Is+30;
                    }

                if(Ib>250)  Ib=Ig=Ir=250;
                SetPixel(hDC,i,Ycenter-y0+j,PALETTERGB(Ir,Ig,Ib));
                }
            }
       Ax=(PointX[3]-PointX[5])/y0;Ay=(PointY[3]-PointY[5])/y0;
       Az=(PointZ[3]-PointZ[5])/y0;Bx=(PointX[4]-PointX[6])/y0;
       By=(PointY[4]-PointY[6])/y0;Bz=(PointZ[4]-PointZ[6])/y0;
       for(j=0; j<=y0; j++)
            {
            y1=R*(y0-j)/(2*y0);
            x0=Xcenter-R/2-y1;
            x1=Xcenter+R/2+y1;
            Cx=PointX[3]-Ax*j;Cy=PointY[3]-Ay*j;Cz=PointZ[3]-Az*j;
            Dx=PointX[4]-Bx*j;Dy=PointY[4]-By*j;Dz=PointZ[4]-Bz*j;
            length=square(Cx,Cy,Cz);
            Cx=Cx/length;Cy=Cy/length;Cz=Cz/length;
            length=square(Dx,Dy,Dz);
            Dx=Dx/length;Dy=Dy/length;Dz=Dz/length;
            for(i=x0;i<=x1;i++)
                {
                I[1]=Cx+(Dx-Cx)*(i-x0)/(x1-x0);
                I[2]=Cy+(Dy-Cy)*(i-x0)/(x1-x0);
                I[3]=(Dz-Cz)*(i-x0)/(x1-x0)+Cz;
                length=square(I[1],I[2],I[3]);
                I[1]=I[1]/length;I[2]=I[2]/length;I[3]=I[3]/length;
                LNN =I[1]*Lxn+I[2]*Lyn+I[3]*Lzn;
                NH = I[1]*Vx+I[2]*Vy+I[3]*Vz;
                NHn = pow(NH,10);
                if(LNN<0) Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ib=Ir=Iaka+Id+Is+30;
                    }
                if(Ib>250)  Ib=Ig=Ir=250;
                SetPixel(hDC,i,Ycenter+j,PALETTERGB(Ir,Ig,Ib));
                }
            }

       x0 = Xcenter -R;
       y0=High*(t)/2.0;
       Ax=(PointX[5]-PointX[3])/(R/2.0);Ay=(PointY[5]-PointY[3])/(R/2.0);
       Az=(PointZ[5]-PointZ[3])/(R/2.0);Bx=(PointX[9]-PointX[7])/(R/2.0);
       By=(PointY[9]-PointY[7])/(R/2.0);Bz=(PointZ[9]-PointZ[7])/(R/2.0);
       for(i=0;i<=R/2;i++)
            {
            y1=i*(t)/2.0+Ycenter;
            Cx=PointX[3]+Ax*i;Cy=PointY[3]+Ay*i;Cz=PointZ[3]+Az*i;
            Dx=PointX[7]+Bx*i;Dy=PointY[7]+By*i;Dz=PointZ[7]+Bz*i;
            length=square(Cx,Cy,Cz);
            Cx=Cx/length;Cy=Cy/length;Cz=Cz/length;
            length=square(Dx,Dy,Dz);
            Dx=Dx/length;Dy=Dy/length;Dz=Dz/length;
            for(j=0;j<=y0;j++)
                {
                I[1]=Cx+(Dx-Cx)*j/y0;
                I[2]=Cy+(Dy-Cy)*j/y0;
                I[3]=(Dz-Cz)*j/y0+Cz;
                length=square(I[1],I[2],I[3]);
                I[1]=I[1]/length;I[2]=I[2]/length;I[3]=I[3]/length;
                LNN =I[1]*Lxn+I[2]*Lyn+I[3]*Lzn;
                NH = I[1]*Vx+I[2]*Vy+I[3]*Vz;
                NHn = pow(NH,10);
                if(LNN<0) Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ib=Ir=Iaka+Id+Is+30;
                    }
                if(Ib>250)  Ib=Ig=Ir=250;
                SetPixel(hDC,x0+i,y1+j,PALETTERGB(Ir,Ig,Ib));
                }
            }

       x0 = Xcenter - R/2;
       y1 = Ycenter + R*(t)/4.0;
       Ax=(PointX[6]-PointX[5])/R;Ay=(PointY[6]-PointY[5])/R;
       Az=(PointZ[6]-PointZ[5])/R;Bx=(PointX[10]-PointX[9])/R;
       By=(PointY[10]-PointY[9])/R;Bz=(PointZ[10]-PointZ[9])/R;
       for(i=0;i<=R;i++)
            {
            Cx=PointX[5]+Ax*i;Cy=PointY[5]+Ay*i;Cz=PointZ[5]+Az*i;
            Dx=PointX[9]+Bx*i;Dy=PointY[9]+By*i;Dz=PointZ[9]+Bz*i;
            length=square(Cx,Cy,Cz);
            Cx=Cx/length;Cy=Cy/length;Cz=Cz/length;
            length=square(Dx,Dy,Dz);
            Dx=Dx/length;Dy=Dy/length;Dz=Dz/length;
            for(j=0;j<=y0;j++)
                {
                I[1]=Cx+(Dx-Cx)*j/y0;
                I[2]=Cy+(Dy-Cy)*j/y0;
                I[3]=(Dz-Cz)*j/y0+Cz;
                length=square(I[1],I[2],I[3]);
                I[1]=I[1]/length;I[2]=I[2]/length;I[3]=I[3]/length;
                LNN =I[1]*Lxn+I[2]*Lyn+I[3]*Lzn;
                NH = I[1]*Vx+I[2]*Vy+I[3]*Vz;
                NHn = pow(NH,10);
                if(LNN<0)  Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ib=Ir=Iaka+Id+Is+30;
                    }
                if(Ib>250)  Ib=Ig=Ir=250;
                SetPixel(hDC,i+x0,y1+j,PALETTERGB(Ir,Ig,Ib));
                }
            }

       x0 = Xcenter + R/2;
       Ax =(PointX[4]-PointX[6])/(R/2.0);Ay=(PointY[4]-PointY[6])/(R/2.0);
       Az=(PointZ[4]-PointZ[6])/(R/2.0);Bx =(PointX[8]-PointX[10])/(R/2.0);
       By=(PointY[8]-PointY[10])/(R/2.0);Bz=(PointZ[8]-PointZ[10])/(R/2.0);
       for(i=0;i<=R/2;i++)
            {
            y1 = (R/2-i)*(t)/2+Ycenter;
            Cx = PointX[6]+Ax*i;Cy=PointY[6]+Ay*i;Cz=PointZ[6]+Az*i;
            Dx = PointX[10]+Bx*i;Dy=PointY[10]+By*i;Dz=PointZ[10]+Bz*i;
            length=square(Cx,Cy,Cz);
            Cx=Cx/length;Cy=Cy/length;Cz=Cz/length;
            length=square(Dx,Dy,Dz);
            Dx=Dx/length;Dy=Dy/length;Dz=Dz/length;
            for(j=0;j<=y0;j++)
                {
                I[1]=Cx+(Dx-Cx)*j/y0;
                I[2]=Cy+(Dy-Cy)*j/y0;
                I[3]=(Dz-Cz)*j/y0+Cz;
                length=square(I[1],I[2],I[3]);
                I[1]=I[1]/length;I[2]=I[2]/length;I[3]=I[3]/length;
                LNN =I[1]*Lxn+I[2]*Lyn+I[3]*Lzn;
                NH = I[1]*Vx+I[2]*Vy+I[3]*Vz;
                NHn = pow(NH,10);
                if(LNN<0)  Ig=Ib=Ir=Iaka;
                else
                    {
                    Id=Kd*LNN*Ilight;
                    Is=Ks*NHn*Ilight;
                    Ig=Ib=Ir=Iaka+Id+Is+30;
                    }
                if(Ib>250)  Ib=Ig=Ir=250;
                SetPixel(hDC,i+x0,y1+j,PALETTERGB(Ir,Ig,Ib));
                }
            }

    }

int RayTracing(double sx,double sy,double sz,
           double dx,double dy,double dz,
           int    depth,
           double Lx[5],double Ly[5],double Lz[5],
           long   Ilight[5],
           PRGB   pRGB,
           double BallX[5], double BallY[5], double BallZ[5],
           double R[5],double ks[5],double kp[5],int Refractionflag )
    {

    RGB    Mid,BK;
    double jx,jy,jz,fx,fy,fz,KS,KP,COSR,Oc,length;
    double rx,ry,rz,px,py,pz,COSP,min_t,mrx,mry;
    double Hx[5],Hy[5],Hz[5];
    int    l,k,i,sign_dx,sign_dy,sign_dz;
    int    flag ;
    int      ui,uj;

    double   LN,NH,NHn,Kd;
    unsigned int   Id,Is;
    unsigned int sumIr,sumIg,sumIb;

    BK.red  = BK.green  = BK.blue  = 255;
    Mid.red = Mid.green = Mid.blue = 0;
    KP = KS = 0;

    pRGB->red   = pRGB->green   = pRGB->blue   = 0;

    if(depth <1 ) return ;

    min_t = 30000.0;
    flag = 0;
    for( i = 1; i < 5; i++)
        {
        rx=(sx-BallX[i]);
        ry=(sy-BallY[i]);
        rz=(sz-BallZ[i]);
        COSR = rx*rx+ry*ry+rz*rz-R[i]*R[i];
        COSP = 2*(dx*rx+dy*ry+dz*rz);
        mry = COSP*COSP-4*COSR;
        if(mry>=0)
            {
            mrx=sqrt(mry);
            px= (mrx-COSP)/2.0;
            py= (-mrx-COSP)/2.0;
            if(fabs(px)<ERROR) px=0.0;
            if(fabs(py)<ERROR) py=0.0;
            if(px>0 || py>0 )
                {
                if(px >0)   pz = px;
                if((py>0)&&(pz>= py))  pz=py;
                if(min_t>pz)
                    {
                    flag = 1;
                    min_t = pz;
                    jx=sx+min_t*dx;
                    jy=sy+min_t*dy;
                    jz=sz+min_t*dz;
                    fx= (jx-BallX[i])/R[i];
                    fy= (jy-BallY[i])/R[i];
                    fz= (jz-BallZ[i])/R[i];
                    KS=ks[i];
                    KP=kp[i];
                    }
                }
            }
        }

     if(!flag)
        {
        sign_dx = dx*1000;
        sign_dy = dy*1000;
        sign_dz = dz*1000;
        if(sign_dx<0 || sign_dy<0 || sign_dz<0)
            {
            if(sign_dx < 0 )
                {
                px=-sx/dx;
                min_t=px;
                }
            if(sign_dy < 0 )
                {
                py=-sy/dy;
                if( min_t>py) min_t = py;
                }
            if(sign_dz < 0 )
                {
                pz=-sz/dz;
                if( min_t>pz) min_t = pz;
                }
            jx=sx+min_t*dx;
            jy=sy+min_t*dy;
            jz=sz+min_t*dz;
            }
        else return 1;
        }

        flag=jx*1000;
        if(flag==0)
            {
            pRGB->red   = 255;
            pRGB->green = 220;
            pRGB->blue  = 255;
            if (
                //这里是文字 HSS
                    (jz<250 &&  jz>100 && jy>50 && jy<75 )  //h
                    ||(jz>175 && jz<200 && jy>=75 && jy<100)//h
                    ||(jz<250 && jz>100 && jy>=100 && jy<125)//h
                    ||(jz<250 && jz>225 && jy>=150 && jy<225)//s1-
                    ||(jz<200 && jz>175 && jy>=150 && jy<225)//s1-
                    ||(jz<125 && jz>100 && jy>=150 && jy<225)//s1-
                    ||(jz<250 && jz>175 && jy>=200 && jy<225)//s1|
                    ||(jz<175 && jz>100 && jy>=150 && jy<175)//s1|
                    ||(jz<250 && jz>225 && jy>=250 && jy<325)//s2-
                    ||(jz<200 && jz>175 && jy>=250 && jy<325)//s2-
                    ||(jz<125 && jz>100 && jy>=250 && jy<325)//s2-
                    ||(jz<250 && jz>175 && jy>=300 && jy<325)//s2|
                    ||(jz<175 && jz>100 && jy>=250 && jy<275)//s2|

                )
                {
                pRGB->red   = 0;
                pRGB->green = 0;
                pRGB->blue  = 200;
                }
            return 1;
            }

         flag=jy*1000;
         if(flag==0)
            {
            pRGB->red   =255;
            pRGB->green = 255;
            pRGB->blue  = 200;
            if (
                //这里是文字DUDU
                    (jz<250 &&  jz>100 && jx>10 && jx<35 )//d1
                    ||(pow(jz-175,2)+pow(jx-35,2)<73*73)&& jx>35//d1
                    && (pow(jz-175,2)+pow(jx-35,2)>50*50)//d1
                    ||(jz>100 && jz<175 && jx>=110 && jx<135)//u1|
                    ||(jz>100 && jz<175 && jx>=160 && jx<185)//u1|
                    ||(jz>100 && jz<125 && jx>=110 && jx<185)//u1-
                    ||(pow(jz-150,2)+pow(jx-235,2)<47*47)//d2
                    &&(pow(jz-150,2)+pow(jx-235,2)>23*23)//d2
                    ||(jz>100 && jz<250 && jx>=260 && jx<285)//d2
                    ||(jz>100 && jz<175 && jx>=290 && jx<315)//u2|
                    ||(jz>100 && jz<175 && jx>=340 && jx<365)//u2|
                    ||(jz>100 && jz<125 && jx>=290 && jx<365)//u2-

                )
                {
                pRGB->red   = 0;
                pRGB->green = 200;
                pRGB->blue  = 0;
                }

            return 1;
            }
         flag=jz*1000;
         if(flag==0)
            {
             //这里是在背景中添加心形图案
            pRGB->red   = 200;
            pRGB->green = 255;
            pRGB->blue  = 255;
            uj=(int)(jx/100);
            ui=(int)(jy/100);
            if(jx-(int)(jx/100)*100<50 && jy-(int)(jy/100)*100<50)
                {
                pRGB->red=200;
                pRGB->green = 0;
                pRGB->blue  = 0;
                }
            else if( uj!=0 )
                {
                if(pow(jx-uj*100-25,2)+pow(jy-ui*100-100,2)<pow(25,2))
                    {
                    pRGB->red=200;
                    pRGB->green = 0;
                    pRGB->blue  = 0;
                    }

                else if(ui!=0 && pow(jx-uj*100-50,2)+pow(jy-ui*100-25,2)<pow(25,2))
                    {
                    pRGB->red=200;
                    pRGB->green = 0;
                    pRGB->blue  = 0;
                    }
                }
            return 1;
            }
     if(Refractionflag == 0)
        {

        for(i=1;i<5;i++)
            {
            length=square((Lx[i]+dx),(Ly[i]+dy),(Lz[i]+dz));
            Hx[i]=(Lx[i]+dx)/length;
            Hy[i]=(Ly[i]+dy)/length;
            Hz[i]=(Lz[i]+dz)/length; }

            sumIr = sumIg = sumIb = 0;
            for( i = 1;i < 5; i++)
                {
                LN=fx*Lx[i]+fy*Ly[i]+fz*Lz[i];

                if(LN>0)
                    {
                    NH=Hx[i]*fx+Hy[i]*fy+Hz[i]*fz;
                    NHn=pow(NH,10);
                    }
                if(LN<0)
                    {
                    Mid.red=0;
                    Mid.green=0;
                    Mid.blue=0;
                    }
                else
                    {
                    Id=(1-KS)*LN*Ilight[i];
                    Is=KS*NHn*Ilight[i];
                    Mid.red=Mid.blue=Mid.green=Id+Is;
                    }
                sumIr += Mid.red;
                sumIg += Mid.green;
                sumIb += Mid.blue;

                }

            Mid.red   =  sumIr ;
            Mid.green =  sumIg ;
            Mid.blue  =  sumIb ;

            COSR=-(fx*dx+fy*dy+fz*dz);
            rx=dx+2*fx*fabs(COSR);
            ry=dy+2*fy*fabs(COSR);
            rz=dz+2*fz*fabs(COSR);
            RayTracing(jx,jy,jz,rx,ry,rz,depth-1,
                Lx,Ly,Lz,Ilight,pRGB,
                BallX,BallY,BallZ,R,ks,kp,0);
            Mid.red   += (0.4*pRGB->red);
            Mid.green += (0.4*pRGB->green);
            Mid.blue  += (0.4*pRGB->blue);

        flag=100*KP;
        if(flag != 0)
            {
            COSR=-(fx*dx+fy*dy+fz*dz);
            COSP=sqrt(1-KP*KP*(1-COSR*COSR));
            px=KP*dx-(COSP-KP*COSR)*fx;
            py=KP*dy-(COSP-KP*COSR)*fy;
            pz=KP*dz-(COSP-KP*COSR)*fz;
            RayTracing(jx,jy,jz,px,py,pz,depth-1,
               Lx,Ly,Lz,Ilight,pRGB,
               BallX,BallY,BallZ,R,ks,kp,2);
            Mid.red   += (0.65*pRGB->red);
            Mid.green += (0.65*pRGB->green);
            Mid.blue  += (0.65*pRGB->blue);
            }
        }

        if (Refractionflag == 1 )
            {
            RayTracing(jx,jy,jz,dx,dy,dz,depth-1,
               Lx,Ly,Lz,Ilight,pRGB,
               BallX,BallY,BallZ,R,ks,kp,0);
            Mid.red   += (0.65*pRGB->red);
            Mid.green += (0.65*pRGB->green);
            Mid.blue  += (0.65*pRGB->blue);

            }

        if (Refractionflag == 2 )
            {
            flag=100*KP;
            if(flag != 0)
                {
                KP=1/KP;
                fx = -fx;
                fy = -fy;
                fz = -fz;
                COSR=-(fx*dx+fy*dy+fz*dz);
                if(acos(COSR)<asin(1/KP))
                    {
                    COSP=sqrt(1-KP*KP*(1-COSR*COSR));
                    px=KP*dx-(COSP-KP*COSR)*fx;
                    py=KP*dy-(COSP-KP*COSR)*fy;
                    pz=KP*dz-(COSP-KP*COSR)*fz;
                    RayTracing(jx,jy,jz,px,py,pz,depth-1,
                        Lx,Ly,Lz,Ilight,pRGB,
                        BallX,BallY,BallZ,R,ks,kp,0);
                    }

                else
                    {
                    px=dx+2*fx*fabs(COSR);
                    py=dy+2*fy*fabs(COSR);
                    pz=dz+2*fz*fabs(COSR);
                    RayTracing(jx,jy,jz,px,py,pz,depth-1,
                        Lx,Ly,Lz,Ilight,pRGB,
                        BallX,BallY,BallZ,R,ks,kp,2);
                    }

                Mid.red   += (0.65*pRGB->red);
                Mid.green += (0.65*pRGB->green);
                Mid.blue  += (0.65*pRGB->blue);
                }
            }
            pRGB->red   = Mid.red;
            pRGB->green = Mid.green;
            pRGB->blue  = Mid.blue;
            return (0) ;
        }

//Ray Tracing
void CGEWork4(HDC hDC)
    {
    double x,y,xbegin,ybegin,zbegin,dx,dy,dz,LX,LY,LZ,length;
    double o1,o2,o3,sum0,sum1;
    double Lx[5],Ly[5],Lz[5];
    double R[5],BallX[5],BallY[5],BallZ[5];
    double Ks[5],Kp[5];
    double Tx[4][4],Ty[4][4],Tz[4][4],P[4][4],A[4],A1[4],B[4],B1[4];
    long   Ilight[5];
    RGB    RGB_VALUE;
    PRGB   pRGB;
    int    MAXDEPTH,i,j,Xcent,Ycent;

    pRGB = &RGB_VALUE;

   /* define ball‘s size . location . Ks . Kp */

    R[1]= 50; BallX[1]=80;BallY[1]=80;BallZ[1]=80;Ks[1]=0.9;Kp[1]=0.0;
    R[2]= 70; BallX[2]=250;BallY[2]=130;BallZ[2]=100;Ks[2]=0.9;Kp[2]=0.0;
    R[3]= 90; BallX[3]=120;BallY[3]=220;BallZ[3]=170;Ks[3]=0.9;Kp[3]=0.95;
    R[4]= 120; BallX[4]=370;BallY[4]=350;BallZ[4]=75;Ks[4]=0.9;Kp[4]=0.9;

   /* define light‘s direction and brightness */

    Ilight[1] = 55;
    Ilight[2] = 55;
    Ilight[3] = 55;
    Ilight[4] = 55;

    LX = LY = LZ = 0.57735;
    Lx[1] = LX /square(LX,LY,LZ);
    Ly[1] = LY /square(LX,LY,LZ);
    Lz[1] = LZ /square(LX,LY,LZ);

    LX=LY=2.504975;LZ=-0.60;
    Lx[2] = LX /square(LX,LY,LZ);
    Ly[2] = LY /square(LX,LY,LZ);
    Lz[2] = LZ /square(LX,LY,LZ);

    LX=LZ=3.704975;LY=-0.60;
    Lx[3] = LX /square(LX,LY,LZ);
    Ly[3] = LY /square(LX,LY,LZ);
    Lz[3] = LZ /square(LX,LY,LZ);

    LZ=LY=3.704975; LX=-0.60;
    Lx[4] = LX /square(LX,LY,LZ);
    Ly[4] = LY /square(LX,LY,LZ);
    Lz[4] = LZ /square(LX,LY,LZ);

    MAXDEPTH=4;
    Xcent = 350;
    Ycent = 260;

    o1 =0;
    o2 =3.1415926 / 4.0;
    o3 =3.1415926 / 4.0;

    for (i = 0;i<4;i++)
        for(j=0;j<4;j++)
            {
            if(i!=j)
                {
                Tx[i][j] = 0.0;
                Ty[i][j] = 0.0;
                Tz[i][j] = 0.0;
                P[i][j] = 0.0;
                }
            else
                {
                Tx[i][j] = 1.0;
                Ty[i][j] = 1.0;
                Tz[i][j] = 1.0;
                P[i][j] = 1.0;}
                }
            Tx[1][1] = Tx[2][2]=cos(o1);
            Tx[1][2] = sin(o1);
            Tx[2][1] = -sin(o1);
            Ty[0][0] = Ty[2][2]=cos(o2);
            Ty[2][0] = sin(o2);
            Ty[0][2] = -sin(o2);
            Tz[1][1] = Tz[0][0]=cos(o3);
            Tz[0][1] = sin(o3);
            Tz[1][0] = -sin(o3);
            P[3][0] = 500;
            P[3][1] = 500;
            P[3][2] = 500;

        for(y=-260;y<250;y++)
            {
            for(x=-350;x<500;x++)
                {

                B[0] = A[0] = x;
                B[1] = A[1] = y;
                A[2] = 1;
                B[2] = 0;
                B[3] = A[3] = 1;

                for(i=0;i<4;i++)
                    {
                    sum0 = sum1 = 0.0;
                    for(j=0;j<4;j++)
                        {
                        sum0 = sum0+A[j]*Ty[j][i];
                        sum1 = sum1+B[j]*Ty[j][i];
                        }
                    A1[i] = sum0;
                    B1[i] = sum1;
                    }

            for(i=0;i<4;i++)
                {
                sum0 = sum1 = 0.0;
                for(j=0;j<4;j++)
                    {
                    sum0 = sum0+A1[j]*Tz[j][i];
                    sum1 = sum1+B1[j]*Tz[j][i];
                    }
                A[i] = sum0;
                B[i] = sum1;
                }

            for(i=0;i<4;i++)
                {
                sum0 = sum1 = 0.0;
                for(j=0;j<4;j++)
                    {
                    sum0 = sum0+A[j]*Tx[j][i];
                    sum1 = sum1+B[j]*Tx[j][i];
                    }
            A1[i] = sum0;
            B1[i] = sum1;
            }

            for(i=0;i<4;i++)
                {
                sum0 = sum1 = 0.0;
                for(j=0;j<4;j++)
                    {
                    sum0 = sum0+A1[j]* P[j][i];
                    sum1 = sum1+B1[j]* P[j][i];
                    }
                A[i] = sum0;
                B[i] = sum1;
                }

            xbegin = A[0];
            ybegin = A[1];
            zbegin = A[2];

            dx = B[0] - A[0];
            dy = B[1] - A[1];
            dz = B[2] - A[2];

            length = square(dx,dy,dz);
            dx   = dx/length;
            dy   = dy/length;
            dz   = dz/length;

            RayTracing(  xbegin,ybegin,zbegin,
                dx,dy,dz,                // direction
                MAXDEPTH,                // depth control
                Lx,Ly,Lz,                // light direction
                Ilight,                  // brightness of light
                pRGB,                    // return RGB values
                BallX,BallY,BallZ,R,     // Ball location and its size
                Ks,Kp,                   // Each ball‘s Ks and Kp
                0);                      // Refraction control

            SetPixel(hDC,x+Xcent,y+Ycent,PALETTERGB(pRGB->red,pRGB->green,pRGB->blue));
            }
        }
    }

//Texture
void CGEWork55(HDC hDC)
{
int Ilight,Ir,Ig,Ib,Ia;
double Hx,Hy,Hz,Lx,Ly,Lz,xn,yn,zn,LN,NHn,NH;
double Id,Is,x,y,z,Ka;
double kd;
double ks,Xcenter,Ycenter,R;
int n;
double PI=3.1415926;
double dis_to_length;

Ilight = 200;
Ia =320;
Ka = 0.2;
Lx=Ly=-0.57735;
Lz=0.57735;
Hx = -0.57735;
Hy = -0.57735;
Hz = 0.57735;

kd=0;
R=100;
Xcenter=150;
Ycenter=150;
SetLUT_GRAY(hDC);
for(y = (-R);y <= R ; y++)
    for( x = (-R);x <= R;x++ )
        {
        if (x*x+y*y <= R*R)
            {
            z=sqrt(R*R-x*x-y*y);
            xn=x/R;
            yn=y/R;
            zn=z/R;
            if (x>0)
                {
                dis_to_length=pow(pow(x,2)+pow(z,2),.5)*sin(PI/4-atan(z/x));
                kd=0.7+.2*sin(2*dis_to_length)+0.05*sin(x);
                }
            else if (x<0)
                {
                dis_to_length=pow(pow(x,2)+pow(z,2),.5)*sin(PI/4-atan(z/x));
                kd=0.7+.2*sin(-2*dis_to_length)+0.05*sin(x);
                }
            else
                {
                dis_to_length=pow(pow(x,2)+pow(z,2),.5)*sin(PI/4);
                kd=0.7+.2*sin(-2*dis_to_length)+0.05*sin(x);
                }
            ks=.01;
//            ks=1-kd;
            LN=xn*Lx+yn*Ly+zn*Lz;
            if(LN>0)
                {
                NH=Hx*xn+Hy*yn+Hz*zn;
                NHn=pow(NH,n);
                }
            if(LN<0)
                {
                Ig=Ia*Ka;
                if (Ig>240)Ig=240;
                Ir=Ib=Ig;
                }
            else
                {
                Id=kd*LN*Ilight;
                Is=ks*NHn*Ilight;
                Ig=(Ka*Ia+Id+Is);
                if (Ig>240)Ig=240;
                Ir=Ib=Ig;
                }
            SetPixel(hDC,Xcenter+x,Ycenter+y,PALETTERGB(Ir, Ig, Ib));
            }
        }
}

//Texture

void CGEWork5(HDC hDC)
{
int Ilight,Ir,Ig,Ib,Ia;
double Hx,Hy,Hz,Lx,Ly,Lz,xn,yn,zn,LN,NHn,NH;
double Id,Is,x,y,z,Ka,xi,yi,zi;
double kd,alpha;
double ks,Xcenter,Ycenter,R;
int n;
double PI=3.1415926;
double dis_to_root;
float G0=13;
int grain;
int Kz=25;

Ilight = 200;
Ia =300;
Ka = 0.2;
Lx=.8;
Ly=.56;
Lz=.7;
dis_to_root=sqrt(Lx*Lx+Ly*Ly+Lz*Lz);
Lx=Lx/dis_to_root;
Ly=Ly/dis_to_root;
Lz=Lz/dis_to_root;
Hx = -0.57735;
Hy = -0.57735;
Hz = 0.57735;

kd=0;
R=100;
Xcenter=150;
Ycenter=250;
SetLUT_GRAY(hDC);
xn=0;
yn=0;
zn=1;

for(y = -HalfEdge;y <=HalfEdge ; y++)
    for( x = -HalfEdge;x <= HalfEdge;x++ )
        {
        z=0;
                dis_to_root=pow(pow(x,2)+pow(y,2),.5);
                if(x!=0)
                    alpha=atan(y/x);
                else
                    alpha=PI/2;
                R =dis_to_root + 1.0*sin(Kal*alpha)+.4*sin(3*Kal*alpha);
                grain = R-(int)(R / G0)*G0;
                if (grain < G0/3)
                    kd = light;
                else
                    kd = dark;
//            ks=.01;
            ks=1-kd;
            LN=xn*Lx+yn*Ly+zn*Lz;
            if(LN>0)
                {
                NH=Hx*xn+Hy*yn+Hz*zn;
                NHn=pow(NH,n);
                }
            if(LN<0)
                {
                Ig=Ia*Ka;
                if (Ig>255)Ig=255;
                Ib=Ir=Ig;
                }
            else
                {
                Id=kd*LN*Ilight;
                Is=ks*NHn*Ilight;
                Ig=(Ka*Ia+Id+Is);
                if (Ig>255)Ig=255;
                Ib=Ir=Ig;
                }
            SetPixel(hDC,Xcenter+x,Ycenter+y,PALETTERGB(Ir, Ig, Ib));
            }

xn=1;
yn=0;
zn=0;

for(yi = 0;yi <=HalfEdge*2+Length*.8; yi++)
    for( xi = 0;xi <=Length*.8;xi++ )
        {
        if (yi>xi)
        if (yi<xi+2*HalfEdge+1)
        if (xi<Length*cos(PI/4))
            {
            y=yi-xi-HalfEdge;
            z=xi/cos(PI/4);
            x=HalfEdge;

                dis_to_root=pow(pow(x,2)+pow(y,2),.5);
                if(x!=0)
                    alpha=atan(y/x);
                else
                    alpha=PI/2;
                R =dis_to_root +z/(.8*Kz)+ 1.0*sin(Kal*alpha+z/Kz)+.4*sin(3*Kal*alpha);
                grain = R-(int)(R / G0)*G0;
                if (grain < G0/3)
                    kd = light;
                else
                    kd = dark;
//            ks=.01;
            ks=1-kd;
            LN=xn*Lx+yn*Ly+zn*Lz;
            if(LN>0)
                {
                NH=Hx*xn+Hy*yn+Hz*zn;
                NHn=pow(NH,n);
                }
            if(LN<0)
                {
                Ig=Ia*Ka;
                if (Ig>240)Ig=240;
                Ir=Ib=Ig;
                }
            else
                {
                Id=kd*LN*Ilight;
                Is=ks*NHn*Ilight;
                Ig=(Ka*Ia+Id+Is);
                if (Ig>240)Ig=240;
                Ir=Ib=Ig;//(Id+Is);
                }
            SetPixel(hDC,Xcenter+HalfEdge+xi,Ycenter+HalfEdge-yi,PALETTERGB(Ir, Ig, Ib));
            }
        }

xn=0;
yn=1;
zn=0;

for(yi = 0;yi <=Length*.8 ; yi++)
    for( xi = 0;xi <= HalfEdge*2+Length*.8;xi++ )
        {
        if (yi<xi)
        if (yi>xi-2*HalfEdge)
        if (yi<Length*cos(PI/4))
            {
            x=xi-yi-HalfEdge;
            z=yi/cos(PI/4);
            y=HalfEdge;

                dis_to_root=pow(pow(x,2)+pow(y,2),.5);
                if(x!=0)
                    alpha=atan(y/x);
                else
                    alpha=PI/2;
                R =dis_to_root + z/(.8*Kz)+1.0*sin(Kal*alpha+z/Kz)+.5*sin(3*Kal*alpha);
                grain = R-(int)(R / G0)*G0;
                if (grain < G0/3)
                    kd = light;
                else
                    kd = dark;
//            ks=.01;
            ks=1-kd;
            LN=xn*Lx+yn*Ly+zn*Lz;
            if(LN>0)
                {
                NH=Hx*xn+Hy*yn+Hz*zn;
                NHn=pow(NH,n);
                }
            if(LN<0)
                {
                Ig=Ia*Ka;
                if (Ig>240)Ig=240;
                Ir=Ib=Ig;
                }
            else
                {
                Id=kd*LN*Ilight;
                Is=ks*NHn*Ilight;
                Ig=(Ka*Ia+Id+Is);
                if (Ig>240)Ig=240;
                Ir=Ib=Ig;//(Id+Is);
                }
            SetPixel(hDC,Xcenter-HalfEdge+xi,Ycenter-HalfEdge-yi,PALETTERGB(Ir, Ig, Ib));
            }
        }

    }

关于光线跟踪算法,可以参考碧云涛在雷锋网的文章《视觉技术的圣杯:光线追踪如何再现真实世界?

时间: 2024-08-02 05:32:17

用于520的20年前的图片的相关文章

雷军20年前作文曝光:我会当一辈子程序员

提到小米雷军,巨匠对其印象之一就是很会营销,特别是很早就打出了"为发烧而生"的口号,吸收了一多量米粉.其实扒扒雷军的年老期间,其实他是一位法度圭表标准员身世,大学读的是合计机专业,对编程有着狂热的欢愉爱好.昔日,由于有伴侣发给他一篇20年前的帖子,雷军在小我大众,号回忆了20年前,那仍是1996年,经由过程德律风线拨号毗邻到西点BBS上飙帖子玩的年月.据雷军回忆,那是一个互联网混沌初开的年月,那是一个BBS和Email几近掌握了全数互联网的年月,那是一个青春的幻想和热血沸腾的年月.雷军

封闭必死:请记住20年前的互联网发生了什么

封闭必死:请记住20年前的互联网发生了什么 试想一下,一个日活跃用户上百万的网络平台. 随着使用越发频繁,人们发现这个网络不仅仅是与家人和朋友沟通的绝佳方式,还有他们曾经在网络上所做的一切事情,作为这个网络的一部分,都能更快.更便捷地完成. 阅读新闻?这个网络有办法让它更快更简单.除了关注它们自己的网站之外,内容出版机构们开始将它们的报道直接发布到这个平台上面. 电子商务?如果购物能够在这个网络平台上完成,为什么要去看不同的电商网站呢?厂商们于是在该平台上打造自己的店铺. 广告?这个平台知道你读

.NET成人礼 | 还记得20年前一起拖过的控件吗?

本文是MVP Ediwang写的回忆一个80后的拖控件的感悟,与君共勉: 每一代人都有记忆里的味道.煤球炉.黑白电视机是属于父母的记忆.而“拖控件”式编程,启蒙了无数像我这样的80后(嗯,89也算80后). 经典旧世 2000 年那个时候,上海这样的城市里也不是每家每户都有电脑,我家也没有电脑.我在学校经常听几位家里条件不错的同学说他们玩电脑的事情.CIH.千年虫等名词让我对电脑有着非常强烈的好奇心.而我第一次体验到计算机,是在我母亲单位的机房里.它是一台卧式机箱.15寸 CRT 凸面屏显示器的

Android学习笔记进阶20之得到图片的缩略图

<1>简介 之前往往是通过Bitmap.Drawable和Canvas配合完成,需要写一系列繁杂的逻辑去缩小原有图片,从而得到缩略图. 现在我给大家介绍一种比较简单的方法:(网上有) 在Android 2.2版本中,新增了一个ThumbnailUtils工具类来是实现缩略图,此工具类的功能是强大的,使用是简单,它提供了一个常量和三个方法.利用这些常数和方法,可以轻松快捷的实现图片和视频的缩略图功能. <2>ThumbnailUtils工具类 常量: OPTIONS_RECYCLE_

Android学习笔记进阶20 之得到图片的缩略图

<1>简介 之前往往是通过Bitmap.Drawable和Canvas配合完成,需要写一系列繁杂的逻辑去缩小原有图片,从而得到缩略图. 现在我给大家介绍一种比较简单的方法:(网上有) 在Android 2.2版本中,新增了一个ThumbnailUtils工具类来是实现缩略图,此工具类的功能是强大的,使用是简单,它提供了一个常量和三个方法.利用这些常数和方法,可以轻松快捷的实现图片和视频的缩略图功能. <2>ThumbnailUtils工具类 常量: OPTIONS_RECYCLE_

20年前,?丝眼中的互联网

亲,那是盖茨,不是我! 我学会了开机,关机和用两个手指轮流揿按键盘,而不是只用一个手指. 亲,读到这里,你笑话我了.别价,这几招让我和工厂里当时比我早一年毕业的所有大学生都区分开来.因为这个青年?丝"会"用电脑,而别人连碰它都不敢. 这是开玩笑?不,这是20多年前山东东部一个偏远小城的一家工厂里发生的真实一幕. 我被安排负责生产调度科里的一台电脑,工作呢,就是把原来手抄的报表,用打印机打出来,然后骑着那辆不用摁铃.前面的人也知道我来了的那辆自行车,把报表分送给厂长和3.4个副厂长.

20.QT-Qpixmap实现图片鼠标缩放,鼠标拖动示例(详解)

通过 QPainter 绘画实现,以本地图片985*740为例 如下图所示: 效果如下所示: 实现原理 主要通过以下函数实现: void QPainter::drawTiledPixmap ( int x, int y, int w int h const QPixmap & pixmap, int sx = 0, int sy = 0 ); //平铺显示pixmap //x y w h :表示绘画区域 //sx sy :表示Qpixmap绘画起始位置 只要算出x y w h sx sy就能实现

3星|《永远的零售》:百货业定位第一人,实操经验是20年前的,对新零售做了少许点评

永远的零售:厉玲的零售经营哲学(吴晓波推荐,百货传奇人物解读新零售,剖析行业本质) 作者是零售业老江湖,“百货业定位第一人”,书中讲的是作者的零售业运营.管理经验,对行业的感悟与洞察,对新零售的点评. 作者的零售业运营经验大致集中在20年以前.对新零售的点评篇幅比较少. 全书信息浓度比同样是零售老江湖的黄若的书要差一颗星,作者的洞察力我认为也比黄若差一颗星. 总体评价3星,有一定参考价值. 以下是书中一些内容的摘抄,#号后面是kindle电子版中的页码,[]中是我根据上下文补充的信息: 1:零售

2星|《创新跃迁》:20年前的旧书了,正好可以做《创新者的窘境》的靶子

创新跃迁:打造决胜未来的高潜能组织 版权页上注明英文版是1997年出版的.亚马逊英文网上看到的最早的版本是2002年的修订本,只有6条评论,算是影响比较小的作品. 书中用苹果举例,当时乔布斯已被赶出苹果还没回归. 作者注意到许多行业领导者被颠覆,也有些行业领导者在竞争中保住了地位.作者的建议:1:行业领导者不要等麻烦来了才想到变革,没有麻烦一定要制造麻烦让公司提前准备:2:可以利用技术创新的周期来实施变革: 作者写书的时候应该还没看过同年出版的<创新者的窘境>.跟后者比,本书正好是靶子.这20