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

    技术2022-08-16  85

    微分差值 透明颜色计算 使用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; }
    Processed: 0.023, SQL: 9