📄 shadesph.cpp
字号:
#include "stdafx.h"
#include <math.h>
#include <stdio.h>
COLORREF ILight RGB(150,150,150); /* 点光源的强度 */
COLORREF IaKa RGB(100,0,0); /* 环境光分量 */
double Lx = 1.0, Ly = 1.0, Lz = 1.0;
//double Lx=0.57735, Ly=0.57735, Lz=0.57735; /* 点光源的光线方向 */
double Vx = 0.0, Vy = 0.0, Vz = 1.0; /* 视线方向 */
double Hx,Hy,Hz; /* 虚拟理想镜面的法向量 */
extern int width,length;
int Xsize , Ysize; /* 视屏大小 */
void ShadeOneSphere(double *kd,double ks,int n,int xcenter,int ycenter,int r,CDC *pDC);
void ShadeSpheres(CDC *pDC)
{
double kd[3]; /* 漫反射系数 */
double ks; /* 镜面反射系数 */
int n; /* 光泽度因子 */
int radius; /* 球半径 */
int xcenter,ycenter; /* 球心坐标 */
int x,y;
double denom;
Xsize = width;
Ysize = length;
radius = (int)(((Xsize>Ysize) ? Ysize:Xsize)/12.5);
/* 清视图区 */
for (x = 0; x < Xsize; x++)
for (y = 0; y < Ysize; y++)
pDC->SetPixel(x,y,0);
/* 计算H */
Hx = Lx + Vx;
Hy = Ly + Vy;
Hz = Lz + Vz;
denom = sqrt(Hx * Hx + Hy * Hy + Hz * Hz);
Hx = Hx/denom;
Hy = Hy/denom;
Hz = Hz/denom;
kd[0] = 0;
kd[1] = 0;
kd[2] = 0;
/* 计算每一个球的真实感图象,并在视屏上显示 */
for (xcenter = radius; xcenter <= Xsize-radius; xcenter += (int)(2.5*radius))
{
n = 5;
ks = 1 - kd[1];
for (ycenter = radius; ycenter <= Ysize-radius; ycenter += (int)(2.5*radius))
{
ShadeOneSphere(kd,ks,n,xcenter,ycenter,radius,pDC);
n *= 2;
}
kd[1] += 0.25;
}
}
void ShadeOneSphere(double *kd,double ks,int n,int xcenter,int ycenter,int r,CDC *pDC)
{
int x,y,z; /* 球面上的坐标 */
double Xn,Yn,Zn; /* 球面法向 */
double LdotN; /* 光线与法线的点积 */
double NdotH;
double NnH; /* 法线N与虚拟镜面法向H的点积的n次幂 */
int Ired,Igreen,Iblue; /* 红、绿、蓝三色的光强 */
/* 对于球面上的各点 */
for (y = -r; y <= r; y++)
for (x = -r; x <= r; x++){
if (x*x + y*y < r*r){
/* 计算球面的Z坐标 */
z = (int)sqrt((double)(r*r-x*x-y*y));
/* 计算球面的法向 */
Xn = (double)x/r; Yn = (double)y/r; Zn = (double)z/r;
/* 计算(LN) */
LdotN = Lx*Xn + Ly*Yn + Lz*Zn;
/* 计算(NH)n */
NnH = 0;
if (LdotN>0){
NdotH = Xn*Hx + Yn*Hy + Zn*Hz;
NnH=pow(NdotH,n);
}
/* 用Phong模型计算光反射强度 */
if (LdotN <= 0){
Igreen = GetGValue(IaKa);
Ired = GetRValue(IaKa);
Iblue = GetBValue(IaKa);
}
else{
Igreen =(int)( GetGValue(IaKa) + GetGValue(ILight) * kd[1] * LdotN + GetGValue(ILight) * ks * NnH);
Ired = (int)( GetRValue(IaKa) + GetGValue(ILight) * kd[0] * LdotN + GetRValue(ILight) * ks * NnH);
Iblue =(int)( GetBValue(IaKa) + GetGValue(ILight) * kd[2] * LdotN + GetBValue(ILight) * ks * NnH);
}
if (Igreen>255) Igreen = 255;
if (Ired>255) Ired = 255;
if (Iblue>255) Iblue = 255;
/* 显示一个象素点 */
pDC->SetPixel(x+xcenter,y+ycenter,RGB(Ired,Igreen,Iblue));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -