前言
学的东西多了,要想办法用出来.C和C++是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容
引入
接续上一篇,讨论图片类型设计出来后在场景中如何表达,以及图片的混合算法.前面的内容属于铺垫和基础,这篇内容和实际联系起来了.
背景图和前景图
这里笔者想先引入两个概念:背景图和前景图.
实际表达的图片中,都是以图片混合而存在的,一片色的图几乎没有存在的空间,例如在当前页面截取一张图:
他外面是个矩阵图,里面有一些字符,还有一个跑道图.此时矩阵图被称作背景图,字符和跑道图是前景图.
在跑道图中,跑道图是背景图,"去查看"这三个字是前景图.
图片的混合
前面的图片类设计出来后,只是说明了图片由一堆点组成,还没有实际显示(当然这里的显示也不是在屏幕上显示,还需要调用虚拟内存写到显卡的寄存器中才行,本贴暂不讨论).
思考:图片作为一个对象或者散点集合,调取后出现在新空间中,最重要的是什么?答案是:位置
而怎样才方便把位置表达出来?答案是:矩阵类对象Matrix作背景图.
示意图:
前面提到过每张图片都有着一个隐藏属性:基点.他其实表示了两个属性:在原来坐标系中x坐标原点和y坐标原点.所以一张图可以被看作:以矩阵类对象为背景图,混合跑道图,生成图a;再以图a(仍然是矩阵类对象)混合"发布博客"这四个字符图.即:图片生成=两次混合
混合算法--规则型图形
借助基点,一个矩阵类对象作辅助,写出对应代码.
形式选择:用全局函数还是类方法来写?如果是Java,纯面向对象的语言,无疑用工具类方法来写.C++可在两者中选择.笔者不想用类方法,因为他能表达更多东西(比如作动画时需要覆盖原有图片),这里就用全局函数来表达了.
注意:每种类型的图,混合算法不一样.以上述图片为例,写出圆角矩阵类和矩阵图混合的代码如下:
//混合圆角矩阵类对象
Matrix& mix_fillet_matrix(short x_ref,short y_ref,Matrix & mx,Fillet_Matrix& fm)
{
//得到指向前景圆角矩阵的迭代器
vector<vector<Reg_Point>>::iterator itfm=fm.fillet_matrix.begin();
vector<vector<Reg_Point>>::iterator itfm_end=fm.fillet_matrix.end(); //得到圆角矩阵总行数
//得到指向背景矩阵的迭代器(指针)
//标记下一行是开始写的,不对,用的是C语言中的方法,即指向二维数组的指针化成指向一维数组的指针
//vector<vector<Reg_Point>>::iterator itmx=mx.matrix.begin()+x_ref*mx.height+y_ref;
//x_ref是圆角矩阵基点,传入背景矩阵时的坐标,因此指向背景矩阵的迭代器,应指向偏移后的那一行
vector<vector<Reg_Point>>::iterator itmx=mx.matrix.begin()+x_ref;
for(int n=0;itfm<itfm+fm.radius;itfm++,n++) //圆角矩阵前r行
//背景矩阵每列指针生成,背景矩阵列指针,需加上偏移量
vector<Reg_Point>::iterator itmxs=(*itmx).begin()+y_ref;
for(itfms=(*itfm).begin();itfms!=(*itfm).end();itfms++){
//背景矩阵指针偏移,第一次前进n个点,以后每行减少1个
itmxs=itmxs+radius-n;
//点信息写入
(*itmxs).red=(*itfms).red;
(*itmxs).green=(*itfms).green;
(*itmxs).blue=(*itfms).blue;
itmxs++;
}
itmx++; //背景矩阵向下偏移一行
}
for(itfm=itfm+fm.radius;itfm<itfm_end-radius;itfm++) //圆角矩阵中间也是矩阵
vector<Reg_Point>::iterator itmxs=(*itmx).begin()+y_ref;
for(itfms=(*itfm).begin();itfms!=(*itfm).end();itfms++){
(*itmxs).red=(*itfms).red;
(*itmxs).green=(*itfms).green;
(*itmxs).blue=(*itfms).blue;
itmxs++;
}
itmx++; //背景矩阵向下偏移一行
}
for(int n=0,itfm=itfm_end-radius;itfm!=itfm_end;itfm++,n++) //圆角矩阵后r行
vector<Reg_Point>::iterator itmxs=(*itmx).begin()+y_ref;
for(itfms=(*itfm).begin();itfms!=(*itfm).end();itfms++){
//背景矩阵指针偏移,第一次进1个点,最后进r个点
itmxs=itmxs+n+1;
(*itmxs).red=(*itfms).red;
(*itmxs).green=(*itfms).green;
(*itmxs).blue=(*itfms).blue;
itmxs++;
}
itmx++; //背景矩阵向下偏移一行
}
return mx;
}
代码说明:
1.x_ref和y_ref是圆角矩阵写入矩阵类对象时的坐标偏移,影响矩阵类对象迭代器的位置
1.看起来有些杂乱,大段重复代码一般不会出现在工程中,只是为了看得清楚一些.就算工程代码出现了较大量重复,只要没人说也没关系(笔者臆想)
2.因为没有实际验证,所以可能有点数错误,但问题应该不大,很好改正不用纠结
3.代码有一个看点:二维数组的遍历,如何从一个二维数组写入另一个二维数组:两边指针偏移,看起来时间复杂度高,但运算量不大.而且既然选择了二维数组无可避免.
4.注意:预设的圆角矩形尺寸小于矩阵类对象,也就是完全能被包括进去
预告
不规则图片的混合算法,混合类图形类型建立
鸣谢
笔者另一篇帖子数据在硬件和软件中的表示-CSDN博客里有求下载链接,如果您感觉有所帮助,请帮忙点击,下载,提高等级