欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-16 17:10:07
...

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

我们先来看效果

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

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

/** Name: 微分插值 与 透明*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<graphics.h>
/*
微分插值模板函数:
参数:
	开始插值	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;
}