微分差值 透明颜色计算 使用C++ 的模板函数 去实现 结合EasyX做一个简单示例
程序员文章站
2022-04-16 17:10:07
...
微分差值 透明颜色计算 使用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;
}
上一篇: 冬日段子夏天赏,老凉快啦!
下一篇: 笑谈男女的有趣句段