⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shadesph.cpp

📁 本系统是一个基于Windows平台
💻 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 + -