数据类设计_图片类设计之8_自由图形类设计_(前端架构)

前言

        学的东西多了,要想办法用出来.C和C++是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容

引入

        前面的内容都是矩阵图形类,现在讨论自由图形类设计

矩阵图形类和自由图形类的差别

        

        左图为矩阵图形类对象,右图为自由图形类对象.矩阵图形类对象单独占据一个矩形框大小的位置,自由图形类对象是单独图形.在拖动时,左边对象带着矩形框,而右边不用. 

自由图形类定义

        自由图形类和前面的不规则图形类是差不多的,只不过当时举了一个字符的例子,算一个特例,现在让自由图形回到他最初的样子---像素图

//自由图形类(像素图)定义
struct Pixel_pic{vector<Pixel_point> pps;    //像素点集合
}//像素点类型定义
struct Pixel_point{short x_cord;short y_cord;short red;short green;short blue;
}

         说明:这里的像素点定义和前面的字符定义有所区别,加上了颜色.原因是节省空间.试想有10000个字符,每个字符平均有50个屏幕点,那么节省空间有10000x50x6=300万字节,即3MB,看起来不大但无颜色的更简洁.

多张像素图的混合

        顾名思义,几张图合成一张图,具有层叠效果,区别于矩阵图形类对象.例如上一张图可以看作是"/"和"\"的组合.

        1>形式选择

        前面矩阵图形类采用函数的写法,这里用类的写法.如果采用"数据类"定义的话,如下

//自由图形类(像素图)定义---不好用
struct Pixel_pic{vector<Pixel_point> pps;    //像素点集合vector<Pixel_pic>   pcs;    //像素图由其他像素图组成
}

        和前面的矩阵类定义比起来,看起来有些别扭,因为矩阵类对象用了散列表,而这里好像也不需要.所以考虑用工具类定义.

        工具类用什么名称呢?前面有提到过类名要使用名词.建议采用generator或者builder,表示"生成器",用Pixel_pic_Builder.

//像素混合器定义
class Pixel_pic_Builder{vector<Pixel_pic> pps;...                    //内容暂定
}

        2>混合算法

        笔者尝试了两种方案,也可以作为一种思维的锻炼.

        方案一

                代码思路:

                1)生成的最终对象,仍是Pixel_pic对象,即"原材料"和"产品"都是相同的数据类型

                2) 在一个矩形方框内混合,每加一张图,每加一个点,去遍历之前存在的点,如果没有,则添加,如果有,则修改.

===============================内容分割线↓=================================

                问题:如何确定矩形方框的大小?有一个办法:修改像素图定义如下   

//更新并略过---自由图形类(像素图)定义
struct Pixel_pic{vector<Pixel_point> pps;    //像素点集合short length;               //图的长度short height;               //图的高度
}

          然而这个是无法确定的,因为考虑到直接叠起来的高度比较高,因此略过这一点.

          对于高度的问题,可以固定一个,例如软件里的一个框,让像素图的高度来适应他.

===============================内容分割线↑=================================

//像素混合器定义---不成熟方案
class Pixel_pic_Builder{public:    //materials原材料像素图集合;result结果像素图Pixel_pic build(vector<Pixel_pic> & materials,Pixel_pic& result){//遍历原材料像素图集合for(msd=materials.begin();msd!=materials.end();msd++){//遍历原材料像素图中的点for(msdd=(*msd).pps.begin();msdd!=(*msd).pps.end();msdd++){  //遍历结果像素图中的点              for(rtd=result.pps.begin();rtd!=result.pps.end();rtd++){//点已存在   if((*msdd).x_cord==(*rtd).x_cord)&& (*msdd).y_cord==(*rtd).y_cord){                             //颜色覆盖 (*rtd).red=(*msdd).red;(*rtd).green=(*msdd).green;(*rtd).blue=(*msdd).blue;}//否则加上这个点elseresult.pps.add(Pixel_point{(*msdd).x_cord,(*msdd).y_cord,(*msdd).red,(*msdd).green,(*msdd).blue});}       }}return result;}           
}

        说明:遍历图的每一个点,同时遍历已生成的结果图里的点,查询是否有坐标重叠.如果坐标已存在,则用新点颜色覆盖;如果坐标未存在,则在结果中加上这个点.

        这个写法非常复杂,而且时间复杂度达到n的3次方了---有一层是像素图动态数组,不算在内的话,复杂度是n的2次方.如果不是没有其他选择方案,不会被用于工程中.

        方案二

                代码思路:用一个辅助的矩阵类对象.

                1>将像素图混合到矩阵类对象中,并记录图中所有点经过的位置.

                2>重新遍历矩阵类对象,取出其中经过位置的点组成像素图.

        1.定义一个辅助矩阵类

//辅助矩阵点定义
struct Assistant_point{bool is_choosed;short red;short green;short blue;
}//辅助矩阵类定义
struct Assistant_matrix{short length;short height;vector<vector<Assistant_point>> aps;
}

                为了让程序清晰,不把所有像素图放一起,而是采用每一张都和矩阵类对象混合.引用上面的工具类来做这件事:

        2.将像素图写入辅助矩阵类对象

//像素混合器定义
class Pixel_pic_Builder{public:Assistant_matrix & build_in(short x_ref,short y_ref,Assistant_matrix & ax,Pixel_pic & source){    //辅助矩阵类对象的初始行指针,定位到被放入像素图的基点位置auto axd=ax.aps.begin()+x_ref;//遍历像素图for(pcd=source.pps.begin();pcd!=source.pps.end();pcd++){axd=axd+(*pcd).x_cord;                    //行指针偏移//*axd表示得到该行,行仍然是一个vector对象,所以调用begin()基点位置,并计算坐标auto axdd=(*axd).begin()+y_ref+(*pcd).y_cord; (*axdd).red=(*pcd).red;(*axdd).green=(*pcd).green;        (*axdd).blue=(*pcd).blue;   (*axdd).is_choosed=true;                   //该点已被选中}//返回辅助矩阵类对象return ax;                                        }}

上面混合了一张图,按照这方法并可以把所有需要混合的图都写入辅助矩阵类对象.

        3.将想要得到的Pixel_pic对象从辅助矩阵类对象中抽出来

        本来可以用前面的build_in函数写在一起,为了看得清楚一些,分成了两个程序来写.

//像素混合器定义---有问题不能用
class Pixel_pic_Builder{public:Pixel_pic & build_out(Assistant_matrix & ax){ //生成一个空的对象表示结果Pixel_pic result();   for (short i = 0; i <ax.height; i++)for (short j = 0; j <ax.length; j++){//如果显示被标记if(ax[i][j].is_choosed){result.pps.push_back(Pixel_point{i,j,ax[i][j].red,ax[i][j].green,ax[i][j].blue});}    }}return result;}
}

        这里没有用二维数组的两次vector遍历,用了C语言一样的[][]来表示元素,意思是一样的.如果不成功,可以改成迭代器遍历.

更新

        果然上面代码有点问题,修改如下:

   Pixel_pic& build_out(Assistant_matrix& ax) {//生成一个空的对象表示结果Pixel_pic result;short i = 0,j=0;for ( auto axd=ax.aps.begin() ; axd!=ax.aps.end();axd++,i++)for (auto axdd = (*axd).begin(); axdd != (*axd).end(); j++) {//如果显示被标记if ((*axdd).is_choosed) {result.pps.push_back(Pixel_point{ i,j,(*axdd).red,(*axdd).green,(*axdd).blue });}}return result;}

        现在可以得到一个以辅助矩阵类对象基点作为基点的像素混合图

问题

        代码里有个问题,辅助矩阵类对象的长和高,像素图的长和高,没有表示.怎么解决?

        1.不解决

        假设辅助矩阵是在ps软件中的画布,给他固定一个尺寸,然后规定像素图的长和高比他小才能用

        2.部分解决

        给像素图设置两个属性,即修改定义如下:        

//自由图形类(像素图)定义
struct Pixel_pic{short height;short length;vector<Pixel_point> pps;    //像素点集合
}

        再写个算法,像素图超过尺寸后截取图像,规定尺寸小于矩阵对象才能混合.

        这样做可能还会有问题.因为限制了图形尺寸功能差许多.

        还可以想到的解决方法:把源像素图放到另一个场景中,根据情况从另一个场景写到当前画布来.

        重申:毕竟是为了开拓思路而写的帖子,不是真正开发个ps软件,写工程级别代码遇到什么问题再说.

小结

        自由图形类的混合算法,从中可以看出解决问题有多种方案,从中选择适当的使用.

        每个类型设计中,属性定义很重要;不过也不要太纠结,想到什么都给他写上去也不会错.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39719.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【学习记录】大模型微调之使用 LLaMA-Factory 微调 Qwen系列大模型,可以用自己的数据训练

一、LoRA微调的基本原理 1、基本概念 LoRA&#xff08;Low-Rank Adaptation&#xff09;是一种用于大模型微调的技术&#xff0c;通过引入低秩矩阵来减少微调时的参数量。在预训练的模型中&#xff0c;LoRA通过添加两个小矩阵B和A来近似原始的大矩阵ΔW&#xff0c;从而减少需…

绿盟CSSP靶场-将已有虚拟机创建为新镜像作为新虚拟机模板

将部署了自定义软件的虚拟机&#xff0c;【保持镜像】将这个在运的虚拟机存为一个新的镜像。 为了保证上传的镜像是完整的&#xff0c;勾选【全量镜像】。 等待镜像上传完成&#xff0c;可以看到刚刚上传的镜像&#xff0c;状态也为已上传。 将镜像从私有改为共享&#xff0c;…

VMWare Ubuntu 详细安装教程

VMWare Ubuntu 详细安装教程 一、下载安装VMware二、下载 Ubuntu 镜像文件三、安装 Ubuntu四、开启虚拟机 一、下载安装VMware 官网下载地址https://www.vmware.com/products/desktop-hypervisor/workstation-and-fusion知乎大佬的博客原文&#xff0c;含下载地址https://zhua…

嵌入式c学习八

练习 一、指针数组与数组指针 #include <stdio.h>int main() {//c是一个指针数组&#xff0c;里面有4个元素每个元素都是指针 char *c[] {"hello", "world", "homed", "gotogo"}; //cp是指针数组&#xff0c;有4个元素&#…

LLaMA-Factory微调大模型

LLaMA-Factory安装 github 下载 LLaMA-Factory项目 创建虚拟环境 conda create -n llama_factory python3.10 激活 activate llama_factorytorch 安装 conda install pytorch2.3.1 torchvision0.18.1 torchaudio2.3.1 pytorch-cuda12.1 -c pytorch -c nvidia依赖安装 …

第一讲 | 解锁C++编程能力:基础语法解析

C入门基础 一、C的第一个程序二、命名空间三、C输入&输出四、缺省参数/默认参数五、函数重载六、引用1.引用的特性2.引用的使用引用做返回值场景 3.const引用只有指针和引用涉及权限放大、缩小的问题&#xff0c;普通变量没有 4.指针和引用的关系 七、inline八、nullptr 一…

【颠覆性缓存架构】Caffeine双引擎缓存实战:CPU和内存双优化,命中率提升到92%,内存减少75%

千万级QPS验证&#xff01;Caffeine智能双缓存实现 92%命中率&#xff0c;内存减少75% 摘要&#xff1a; 本文揭秘千万级流量场景下的缓存革命性方案&#xff01;基于Caffeine打造智能双模式缓存系统&#xff0c;通过冷热数据分离存储与精准资源分配策略&#xff0c;实现CPU利…

JVM 03

今天是2025/03/24 15:21 day 11 总路线请移步主页Java大纲相关文章 今天进行JVM 5,6 个模块的归纳 首先是JVM的相关内容概括的思维导图 5. 优化技术 JVM通过多种优化技术提升程序执行效率&#xff0c;核心围绕热点代码检测和编译优化实现动态性能提升。 热点代码检测 JVM…

wordpress-网站百宝箱插件

含置顶,网页宠物, 哀悼, 禁止复制, 禁止查看源码, 弹幕, WP优化,媒体分类,预加载,定时发布,在线客服, 留言板, 手机客服, 网站背景, 公告, 跑马灯, 水印, 分享, 打赏, 海报图, 广告,数据库管理,图片加载特效。等综合功能插件

Git 钩子:特定操作脚本

Git 钩子 在特定 Git 操作发生时自动触发的脚本&#xff1b; 可以从提交规范、代码质量、自动化流程、分支管理、安全性检查等多个方面进行配置&#xff0c;帮助团队提高开发效率和代码质量&#xff1b; 本地 记录提交检验 commit-msg 修改&#xff1a;\test\.git\hooks\c…

职坐标:互联网行业职业发展路径解析

内容概要 当前&#xff0c;互联网行业正以指数级速度重塑全球产业格局。数据显示&#xff0c;我国互联网市场规模在2019年上半年实现17.9%的同比增速&#xff0c;而随着工业互联网、5G等前沿技术的加速落地&#xff0c;这一增长趋势仍在强化。工信部近期发布的《新型信息基础设…

红数码影视(RED Digital Cinema)存储卡格式化后的恢复方法

红数码影视(RED Digital Cinema)的摄像机可以生成两种RAW级高清视频文件&#xff0c;一种是R3D&#xff0c;一种是MOV。其中MOV属于苹果(apple)公司的QT视频封装结构&#xff0c;使用的视频编码是Apple ProRes;而R3D则是RED公司自创的RAW视频文件&#xff0c;这种文件解码需要使…

Gitee上库常用git命令

Gitee上库常用git命令 1、Fork 项目2、个人仓库修改3、追加提交4、创建PR5、多笔commit合一 1、Fork 项目 2、个人仓库修改 git add . // -s 表示自动添加邮箱签名信息&#xff0c;-m表示其后跟随commit描述 git commit -sm “add transition freeze” git push origin [目标…

阿里开源的免费数据集成工具——DataX

企业里真实的数据流转是什么样子的呢&#xff1f; 左侧描述了一个企业真实的样子&#xff0c;我们总是需要把数据从一个地方搬到另一个地方&#xff0c;最后就是搬来搬去搬成了一张张解不开的网。 右侧则表达了使用DataX为中心实现数据的同步。 什么是DataX DataX是一个异构…

SpringBoot学习笔记(主)

文章目录 SpringBoot概述自动装配&#xff08;部分&#xff09;概述原理简述相关解释源码位置EnableAutoConfigurationAutoConfigurationImportSelector 配置文件yaml语法单双引号列表多行字符串 配置文件的位置和加载顺序配置文件取值运行jar包 Springboot整合springmvc自动管…

python多线程和多进程的区别有哪些

python多线程和多进程的区别有七种&#xff1a; 1、多线程可以共享全局变量&#xff0c;多进程不能。 2、多线程中&#xff0c;所有子线程的进程号相同&#xff1b;多进程中&#xff0c;不同的子进程进程号不同。 3、线程共享内存空间&#xff1b;进程的内存是独立的。 4、同一…

docker 安装部署 canal

1 mysql 安装 1.1 拉取镜像 docker pull mysql:8.4.41.2 创建挂载目录 mkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/confmkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/datamkdir -p /user/lzl/tool/docker/mysql/mysql_8.4.4/home/log1.3 编辑配置文…

基于SpringBoot的图书借阅小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

ElasticSearch快速入门--实现分词搜索

分词题目搜索 使用Elasticsearch实现题目数据的存储和分词搜索&#xff0c;需要将数据库的数据同步到 Elasticsearch。 ElasticSearch入门 ElasticSearch&#xff08;简称ES&#xff09;是一个开源的分布式搜索和数据分析引擎&#xff0c;用Java开发并且是当前最流行的开源的…

debug - 安装.msi时,为所有用户安装程序

文章目录 debug - 安装.msi时&#xff0c;为所有用户安装程序概述笔记试试在目标.msi后面直接加参数的测试 备注备注END debug - 安装.msi时&#xff0c;为所有用户安装程序 概述 为了测试&#xff0c;装了一个test.msi. 安装时&#xff0c;只有安装路径的选择&#xff0c;没…