一些关于空间数据结构的简单研究与实现

1.前言

首先,我们来了解一下计算机中的“视图”“图形”等这些概念。我们日常的语境当中在说“视图”、“照片”、“图形”等等这些和图像有关的概念时,一般都认为它单纯指代一个具有视觉效果的画面——比如高考卷子上立体几何的那个题,你会把它对应到“图形”的概念上;你相册里面那张让你看了就来气的跟前对象的合照,你会把它对应到“照片”的概念上,等等等等。不过在计算机中,“视图”“图像”这些概念的涵义还包含了其他的方面,对于一个图像,计算机所要关注的不止是它呈现的视觉效果,还要使用合适的数字格式存储图像,并按照用户的要求对图像进行分析、处理和加工。我们可以把计算机中的“视图场景”看作一个“虚拟的视图场景”:它在概念上更多地指代的是对图像的数字格式存储以及处理加工的相关操作,不妨回想一下我们前面叙述“空间数据结构”的时候所说的“保存图元信息”“定位查找元素”这些关键词,就对应的是这样的概念,很好理解,数字格式便是图像在计算机中的存在形式——硬盘的体积一共就那么大总不应该是相纸做的吧,那些体积的相纸肯定不可能放得下各位那么多的学习资料🐶🐶。这也是前面为什么要用“虚拟”一词,在计算机中说到“图像”“视图”等等时,我们不应直接以日常的语境将它理解成一幅纯粹的“视觉画面”,而是要关注到计算机中实际存储并操作的对象——“数字格式的图像”。我们下面的内容当中也都基于上述概念,讨论的是“数字格式的图像”。

假如我们现在要设计一个视图场景(Scene),在其中包含很多图元对象(Item)。就像这样:

image-20240620173747423

阅读全文

LString::format

1.前言

字符串格式化是非常广泛的需求。对比C++格式化输出的几种方法:

(1)printf 类格式化输出

C 标准库中的 printf 类函数, 实际上是非常广泛使用的。他们主要的问题是不安全 (既不类型安全, 也可能造成缓冲区的溢出), 以及无法拓展 (无法兼容更多类型)。

(2)C++ 的流式 I/O

cout 之类的做到了类型安全, 也做到了拓展性, 但使用起来比较麻烦。而就其实现上来说, 效率也并不见得高。

如果想输出一个浮点数并保留小数点之后 3 位, printf 只需要 %.3f, 而 cout 需要:

1
2
3
#include <iomanip>
#include <iostream>
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(3) << 0.;

这使用起来很麻烦. 更不要说如果你想格式化 5 个参数, 就可能要输入 10 个 << 操作符了。

(3)fmtlib/std::format

鉴于传统C++格式化方法的局限性,fmtlib被开发出来,并在C++20标准中被引入为std::format库,旨在提供一种更现代、更安全、更灵活的格式化方法。引入它们的主要动机包括:

  1. 提高可读性fmtlib/std::format采用了一种更加简洁、易懂的语法,使得格式化字符串更具可读性。
  2. 增强类型安全fmtlib/std::format在编译期间就可以检查参数类型的正确性,从而降低运行时错误的风险。
  3. 扩展功能fmtlib/std::format支持自定义类型的格式化,同时兼容宽字符和多字节字符集。这使得开发人员能够满足更为复杂的格式化需求。
  4. 性能优化fmtlib/std::format设计时充分考虑了性能问题,相比传统的格式化方法,它在许多场景下能够提供更高的性能。

总之,fmtlib/std::format旨在解决传统C++格式化方法的问题,并为开发者提供一种更现代、更安全、更灵活的格式化工具。

阅读全文

关于UUID的简单研究

1.基本介绍

UUID(Universally Unique Identifier),中文名为“通用唯一识别码”,目的是让分布式系统中的所有元素都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定,这样每个人都可以创建不与其它人冲突的UUID。RFC 4122文档规定了规范版本的UUID,另外还有微软使用的GUID等。本文将研究RFC 4122文档规定的UUID。

2.RFC文档规定的UUID格式以及版本

RFC文档规定,UUID是一个32位的16进制数,长度为16字节(128 bit),一般表示为{hhhhhhhh-hhhh-Mhhh-Nhhh-hhhhhhhhhhhh}即{8-4-4-4-12}的标准格式。十六进制位M表示UUID版本,在RFC规范下M可选值为1,2,3,45;十六进制N表示UUID变体,该位固定为10xx,因此可选值为8,9,a,b。RFC 4122规定了5个版本的UUID实现算法,即V1,V2,V3,V4,V5。它们各自的特点如下:

UUID V1:基于时间的UUID

基于时间的UUID通过计算当前时间戳、随机数和机器MAC地址得到。由于在算法中使用了MAC地址,这个版本的UUID可以保证在全球范围的唯一性。但与此同时,使用MAC地址会带来安全性问题,这就是这个版本UUID受到批评的地方。如果应用只是在局域网中使用,也可以使用退化的算法,以IP地址来代替MAC地址。

UUID V2:DCE安全的UUID

DCE(Distributed Computing Environment)安全的UUID和基于时间的UUID V1算法相同,但会把时间戳的前4位置换为POSIX的UID或GID。这个版本的UUID在实际中较少用到。

UUID V3:基于名字空间与给定字符串构造的UUID(MD5)

通过计算名字空间与给定字符串的MD5散列值得到,其中名字空间是由标准规定的一个16字节值。这个版本的UUID保证了:相同名字空间中不同字符串生成的UUID的唯一性;不同名字空间中的UUID的唯一性;相同名字空间中相同字符串的UUID重复生成是相同的。

UUID V4:随机UUID

根据随机数,或者伪随机数生成UUID。

UUID V5:基于名字空间与给定字符串构造的UUID(SHA1)

和UUID V3算法类似,只是散列值计算使用SHA1算法。

除此之外,还有一个特殊种类的UUID:Nil UUID,各位均为0,即{00000000-0000-0000-0000000000000000}。

阅读全文