小编典典

读取有损文件格式(PRC),导致精度问题

algorithm

我开始制作各种3D文件格式的查看器,而以前使用的那些格式直到我进入PRC文件(这是可以嵌入PDF的受支持的3D格式之一)后才构成问题。我可以从PDF中提取所有数据并显示以无损方式编码的那些模型,但是当我尝试对它们所谓的“高度压缩的镶嵌效果”进行解码时,遇到了一个我认为是精度问题的问题,但是我不太知道如何解决它或在哪里寻找解决方案。

本质上,这是一种有损格式,其作用是获取原始(基于浮点的)顶点坐标,并使用公差值将这些坐标除以该坐标,然后将结果四舍五入为最接近的整数。遍历网格以对所有三角形进行编码时,只有第一个三角形存储了绝对值,其余三角形始终基于先前的相邻三角形,并以共享边的中部为原点构建局部坐标系,沿着共享边为x轴,三角形法线为z轴。然后,y轴只是这些轴的叉积的结果,并使用这3个局部轴来存储新三角形第三点的坐标。

我的系统总体正常运行,对于没有太多三角形的简单模型,它也能很好地工作,但是一旦模型变得更复杂,结果就全错了,似乎离最后一个绝对坐标越远,则越大偏差是。

在下面的示例图片中,您可以在左侧看到预期的结果(在Adobe
Reader中呈现),而在右侧可以看到。这个模型本质上有一个内部和一个我们的部分,在这种情况下,内部部分由一个绝对三角形组成,后面是相对的三角形(而外部部分主要由绝对坐标组成,这就是为什么在我看来正确的原因),以及从内圈到外圈的遍历。在Adobe渲染中,您可以看到这些线应该或多或少地径向向外指向,而在我的视线中,从大约第四个“圆圈”开始,事情就开始出错:

预期结果在左侧,我的结果在右侧

我目前对此深感困惑,并且不太了解如何解决此问题。我发现进行较小的更改(例如将double更改为float或反之亦然)会对结果产生巨大的影响,很快会使结果变得更糟。但从本质上讲,我遵循该规范,该规范要求对所有计算使用双精度浮点变量,并使用其自己的计算平方根的实现(对轴进行归一化)。例如,通过使用sqrt函数而不是普通数学库中的sqrt函数,结果已经更好了(不这样做,我什至无法像上图所示那样接近)。

但我想知道这里是否存在某种数学方面的问题?或其他可能有用的想法?同样在该特定模型中,所有值似乎都足够大,因此不应由于缺乏浮点格式的精度而导致数据丢失。规范中也有一些特殊情况,如果y轴或z轴太短(<FLT_EPSILON),则必须使用另一种解决方案,但是在此特定模型中,if
<FLT_EPSILON情况也永远不会触发。

仅供参考,以下是有关点编码的描述(但没有更多有关解码细节的信息):

中国规范中有关如何编码点的信息

任何输入将不胜感激。如果需要,我可以提供更多数据,信息,示例,规格摘录等。


阅读 302

收藏
2020-07-28

共1个答案

小编典典

根据我以前在PRC的经验,这很像是在错误的位置应用了对象偏移量(我认为这称为原点偏移量)的问题。

由于每个新顶点都基于前一个顶点,并使用基于最后一个三角形的局部坐标系来获取新三角形的第三个点,因此,这种格式的误差似乎非常非常快地增长,并且有损格式也无济于事。在我的原始方法中,我尝试计算所有三角形,然后在最后应用偏移量以将其放置在正确的位置,从而导致看起来与您的问题相似的问题。

通过仅将其更改以将偏移量应用于“绝对顶点”(即,在未修改的情况下读取的那些,并且在开始新的三角形时就充当了“锚点”),我能够解决此问题。

当然,作为中华人民共和国,您可能还需要解决其他各种问题,而我不确定您是否已经这样做。官方ISO规范中的很多内容都是错误的,没有提及的其他内容(例如,当您应该重新计算法线而不是从文件中获取明确的法线时),诸如霍夫曼压缩之类的东西有误,等等。如果可以的话避免它,然后最好不执行它;-)

2020-07-28