微分差值 透明颜色计算 使用C++ 的模板函数 去实现 结合EasyX做一个简单示例

微分差值 透明颜色计算 使用C++ 的模板函数 去实现 结合EasyX做一个简单示例

我们先来看效果

微分差值 透明颜色计算 使用C++ 的模板函数 去实现 结合EasyX做一个简单示例_第1张图片
微分差值 透明颜色计算 使用C++ 的模板函数 去实现 结合EasyX做一个简单示例_第2张图片

那么,下面直接上代码,代码注释完成,是一个完整的控制台应用程序,使用VS可正常编译运行,前提是你有安装EasyX库

/** Name: 微分插值 与 透明*/
#include
#include
#include
#include
#include
/*
微分插值模板函数:
参数:
	开始插值	start
	结束插值	end
	微分率		rate
返回值:
	插值的值
描述:
	微分差值,是指微分率在[0-1]区间变化,给定插值区间和微分率之后,
	给出当前微分率对应的插值
	微分率越低越接近开始插值,越大越接近结束插值
	常常用于给定两点确定直线的某一个微分点
*/
template<typename T,typename E>
T AlgoSmooth(T start, T end, E rate)
{
	return start + rate*(end-start);
}

/*
透明计算模板函数:
参数:
	前端颜色	front
	后端颜色	behind
	透明率		rate
返回值:
	混合之后的颜色
描述:
	透明计算,原本用于计算机图形学中,计算一个透明材质透明之后,显示
	材质本身颜色与后端隐藏物颜色的混合颜色
	常常用于参数的混合
*/
template<typename T,typename E>
T AlgoTransparent(T front, T behind, E rate)
{
	return front*rate + behind*(1.0-rate);
}
/*
以下三个函数用于获取Windows颜色COLORREF中的红绿蓝分量值
AABBGGRR
*/
int getR(COLORREF c)
{
	return c & 0xff;
}
int getG(COLORREF c)
{
	return (c>>8) & 0xff;
}
int getB(COLORREF c)
{
	return (c>>16) & 0xff;
}
/*
用于计算两点之间的距离
*/
double distance(int x1,int y1, int x2, int y2)
{
	return sqrt(pow(x2-x1,2.0)+pow(y2-y1,2.0));
}
/*
这里,就用微分差值和透明计算去绘制一张图片,
绘制GUI库使用基于GDI的封装库EasyX
实现效果:
主对角线使用微分差值,进行绘制一个渐变色
副对角线使用透明计算,进行绘制一个透明混合颜色
*/
int main(int argc, char * argv[])
{
	srand((unsigned int)time(NULL));
	//定义窗口大小
	int winWid = 720;
	int winHei = 480;
	initgraph(winWid, winHei);

	//定义主对角线的起止点坐标和颜色信息
	POINT ps = {0,0};
	POINT pe = { winWid, winHei };
	COLORREF cs = 0x2255ff;
	COLORREF ce = 0xff6622;

	//副对角线的颜色值
	COLORREF tr = 0x00ff00;
	COLORREF bl = 0xff0000;
	
	while (1)
	{
		//获取X的变化区间,这里直接使用X区间的2倍,也可以自己使用自己的精度(例如:dx=1000),做*2处理时为了微分程度大于实际度量,
		//这样虽然重复绘制,但是能保证不会出现条纹(未进行颜色设置导致)
		int dx = pe.x - ps.x;
		dx *= 2;
		//对X进行微分
		for (int i = 0; i < dx; i++)
		{
			//获取微分率
			double rate = i*1.0 / dx;
			//获取此微分率下的坐标和颜色信息
			int px = AlgoSmooth(ps.x, pe.x, rate);
			int py = AlgoSmooth(ps.y, pe.y, rate);
			int pr = AlgoSmooth(getR(cs), getR(ce), rate);
			int pg = AlgoSmooth(getG(cs), getG(ce), rate);
			int pb = AlgoSmooth(getB(cs), getB(ce), rate);
			//绘制像素
			putpixel(px, py, RGB(pr, pg, pb));
			
			//因为主对角线将整个图形分为上下两个三角形,因此进行两个循环绘制这两个部分
			//计算此时主对角线上的点到右上角的距离,这是最长长度
			double maxDis = distance(px, py, winWid, 0);
			for (int j = py-1; j >=0; j--)
			{
				//计算向上的点到右上角的距离
				double curDis = distance(px, j, winWid, 0);
				//获取透明度
				double ra = curDis / maxDis;
				//计算透明之后的颜色值
				int cr = AlgoTransparent(pr, getR(tr), ra);
				int cg = AlgoTransparent(pg, getG(tr), ra);
				int cb = AlgoTransparent(pb, getB(tr), ra);
				putpixel(px, j, RGB(cr, cg, cb));
			}
			maxDis = distance(px, py, 0, winHei);
			for (int j = py + 1; j < winHei; j++)
			{
				double curDis = distance(px, j, 0, winHei);
				double ra = curDis / maxDis;
				int cr = AlgoTransparent(pr, getR(bl), ra);
				int cg = AlgoTransparent(pg, getG(bl), ra);
				int cb = AlgoTransparent(pb, getB(bl), ra);
				putpixel(px, j, RGB(cr, cg, cb));
			}
		}
		cs = ce;
		ce = RGB(rand() % 255, rand() % 255, rand() % 255);
		tr = RGB(rand() % 255, rand() % 255, rand() % 255);
		bl = RGB(rand() % 255, rand() % 255, rand() % 255);
	}
	
	closegraph();
	return 0;
}

你可能感兴趣的:(C++,开发学习)