日记:色斑图制作之 kriging.js 颜色算法修改回忆记录

5 篇文章 0 订阅
3 篇文章 0 订阅

关联文章:色板图制作及后端无人值守自动出图kriging.js+chrome+html2canvas.js+DOS+BIGEMAP超低成本实现气象要素色斑图_jessezappy的博客-CSDN博客

当初改了几版,没有记录,现在看不懂了,赶快回忆记录一下:

回忆记录一下 kriging.js 的修改要点:

原版绘图,不能根据值来指定颜色,如下算法:

                z = (grid[i][j]-grid.zlim[0])/range[2];
                if(z<0.0) z = 0.0;
                if(z>1.0) z = 1.0;
                ctx.fillStyle = colors[Math.floor((colors.length-1)*z)]; 

            其仅将计算得到的值锁定在 0 到 1 区间,根据值在这个区间的比例,取得对应比例在色卡数组中的位数以该位数颜色为其颜色。
            也就是说,若你设定的值范围是 0 到 10 ,那么如果最后计算的点中有超过 10 的值,那么其最大值将取代 10 成为颜色定义的上限值
            这样就无法指定值与颜色的关系,所以这里必须修改。
            
一、  修改为,增加一个判断单点值位于设定值具体位置的函数:

                getaidx = function(v,d) {
                    for(let i=0;i<d.length;i++)
                        if(v<=d[i]){
                            return i;//根据值来选定颜色索引号,小于等于
                        }
                    return d.length;
                };

            绘图时的值计算为 Z 值范围也需要修改为直接使用具体值:                

kriging.plot = function(canvas, grid, xlim, ylim, colors,idx) //将设定值数组 idx 传入 
//原始:kriging.plot = function(canvas, grid, xlim, ylim, colors)
                    ....
z =grid[i][j];//  原始:(grid[i][j]-grid.zlim[0])/range[2];//此处可用值直接设置颜色编号20201210 
// if(z<0.0) z = 0.0;
// if(z>1.0) z = 1.0;//z=0.5;
ctx.fillStyle =colors[getaidx(z,idx)];//根据值来选定颜色索引号,小于等于// 原始:colors[Math.floor((colors.length-1)*z)];

            如此即可实现绘图值与颜色的准确对应关系,而不是象原先的设定值范围无效。
            调用方法也做对应调整,增加传入设定值数组:

kriging.plot(canvas, grid,[extent[0], extent[2]], [extent[1], extent[3]], params.colors,params.idx);
//原始:kriging.plot(canvas, grid,[extent[0], extent[2]], [extent[1], extent[3]], params.colors);  

二、同时,为了用两个点之间的渐变颜色作为全图绘图颜色,还可增加另一个颜色算法:

                function getaidx2(v,d,c){
                    if(v<d[0]){return c[0];}
                    if(v>d[1]){return c[c.length-1];}//数组最大值为c.length-1
                    return c[Math.round((c.length-1)*(v-d[0])/(d[1]-d[0]))];//直接返回颜色值,因此渐变颜色为100个起步,故用此算法提高运算速度,不再象 getaidx 的使用循环
                }

            颜色选择处同样修改为

                kriging.plot = function(canvas, grid, xlim, ylim, colors,idx)
                    ...
                z =grid[i][j];//原始: (grid[i][j]-grid.zlim[0])/range[2];//此处可用值直接设置颜色编号20201210 
                // if(z<0.0) z = 0.0;
                // if(z>1.0) z = 1.0;//z=0.5;
                ctx.fillStyle=getaidx2(z,idx,colors);

            同时,色卡设置为渐变色的起点和终点,设定值也改为起点和终点,不再是一组数值序列:

var ctb=[{"v":[6,17],"c":["#C5FCC5","#008000"]},
         {"v":[6,17],"c":["#cef7ef","#00804e"]},
         {"v":[28,39],"c":["#ffff84","#6b0400"]},
         {"v":[0.9,1.6],"c":["#efffce","#548000"]},
         {"v":[101,128],"c":["#ffcece","#aa0000"]},
         {"v":[16,23],"c":["#ffebce","#aa5000"]}
        ];//自定义色板
    ...
//cid为Url传入参数,对应绘图类型。
carr=colorSplit(ctb[cid].c,100);//    colorSplit 用于将两个点之间的颜色分为指定渐变层次的颜色数组 //   ctb[cid].c;
params.colors=carr;
valarr=ctb[cid].v;
params.idx=valarr; 

             
            同样调用方法也做对应调整,增加传入设定值数组:

kriging.plot(canvas, grid,[extent[0], extent[2]], [extent[1], extent[3]], params.colors,params.idx);

三、 下一步,考虑在一那样的指定多点颜色之间进行渐变

先附上颜色渐变算法,

function colorSplit(c,n){
	var c0="",c1="";
	var sR=0,sG=0,sB=0;
	var eR=0,eG=0,eB=0;
	var R=0,G=0,B=0;
	var sctmp="";
	var f=1/3;
	var cs=[];
	c0=c[0];c1=c[1];
	c0=vreplace(c0,"#","");c1=vreplace(c1,"#","");
    sR = parseInt("0x" + mid(c0, 1, 2))
    sG = parseInt("0x" + mid(c0, 3, 2))
    sB = parseInt("0x" + mid(c0, 5, 2))
    
    eR = parseInt("0x" + mid(c1, 1, 2))
    eG = parseInt("0x" + mid(c1, 3, 2))
    eB = parseInt("0x" + mid(c1, 5, 2))
	R=eR-sR;G=eG-sG;B=eB-sB;
	for(var i=0;i<=n;i++){
		f=i/n;
		sctmp="#"+ right("00"+(Math.round(sR+f*R)).toString(16),2)+right("00"+(Math.round(sG+f*G)).toString(16),2)+ right("00"+(Math.round(sB+f*B)).toString(16),2);
		//console.log(sctmp);
		cs.push(sctmp);
	}
	//console.log(cs);
	return cs;
}

多点颜色渐变算法等得闲再补充:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
A year and a half year ago, I published this article to the Codeguru site and got a number of requests about the Kriging algorithm contour map. Unfortunately, my project was changed shortly after that article and later I quit the company so I couldn‘t find time to finish this Contour business. A week ago, I happened to need a contour map again so I decided to solve the Kriging algorithm. I searched the Internet for a commercial library but they all look ugly and hard to use. So, I made up my mind to make my own algorithm. The Kriging algorithm is easy to find, but this algorithm needs a Matrix and solver (LU-Decomposition). Again, I couldn‘t find suitable code for this. I tried to use GSL first but this made my code too big and was slower. Finally, I went back to "Numerical Recipe in C"—yes, that horrible-looking C code—and changed the code there to my taste.If you read this article before, the rendering part hasn‘t been changed much. I added the Kriging algorithm and revised the codes a little bit. Following is the Kriging Algorithm:templatedouble GetDistance(const ForwardIterator start, int i, int j){ return ::sqrt(::pow(((*(start+i)).x - (*(start+j)).x), 2) + ::pow(((*(start+i)).y - (*(start+j)).y), 2));}templatedouble GetDistance(double xpos, double ypos, const ForwardIterator start, int i){ return ::sqrt(::pow(((*(start+i)).x - xpos), 2) + ::pow(((*(start+i)).y - ypos), 2));}templateclass TKriging : public TInterpolater{public: TKriging(const ForwardIterator first, const ForwardIterator last, double dSemivariance) : m_dSemivariance(dSemivariance) { m_nSize = 0; ForwardIterator start = first; while(start != last) { ++m_nSize; ++start; } m_matA.SetDimension(m_nSize, m_nSize); for(int j=0; j<m_nSize; j++) { for(int i=0; i<m_nSize; i++) { if(i == m_nSize-1 || j == m_nSize-1) { m_matA(i, j) = 1; if(i == m_nSize-1 && j == m_nSize-1) m_matA(i, j) = 0; continue; } m

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jessezappy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值