我正在研究深度排序问题,这是我构建的一个示例案例
有两个平面,一个悬浮在另一个之上,它们被分成矩形多边形。每个多边形由它的“真实世界”坐标定义,并且用相机和视图投影定义以产生透视图,如图所示。生成示例多边形的跟踪打印输出
y=33
此样本属于绿色平面v0 to v4 = (13,33,32.7),(29,33,32,7),(29, 33,7.2) and (13,33,7.2)
,非投影顶点为p(i)
使用标准相机和视图模型的投影坐标如下所示。如果-1 < p(i).x,p(i).z,p(i).z < 1
是投影坐标,那么p(i)(x,y,z)
。第四个值是均匀W坐标,当准备渲染分为每个Zn=depth of nearest vertex
时,它被保留为参考值,因为它给出了从“相机”到给定顶点的垂直平面的距离。
第二个方括号中的第三列是投影的Z值,对于此问题,重要 值Zf=depth of farthest vertex
和class Extent implements Comparable<Extent> {
double Zn;
double Zf;
@Override
public int compareTo(Extent ext2) {
if (Zn < ext2.Zf) return 1;
if (ext2.Zn < Zf) return -1;
return 0;
}
}
问题
这个问题是由上述所有因素推动的,但也与图形渲染的任何知识无关。我的动机是主要根据 Z值
根据Painter's algorithm,对两个多边形之间的渲染顺序的第一次检查是Z-near和Z-far是否分开,并且应该暗示明确的空间分离。
比较的简化摘录
java.lang.IllegalArgumentException: Comparison method violates its general contract
我的问题
当我对一大组多边形进行比较时,有时我会得到一个
{{1}}例外。虽然渲染通常如上所述看起来很好,但有时它会失败。但是为什么,我一直无法找到一个失败案例,并且不应该以这种方式比较两个最大值,最小值总是暂时的?
有人知道一个会失败的示例集,会受到这种比较吗?或许,您是否能够在我的方法中发现逻辑错误? (虽然比较方法的内部洞察是主要的探究,如果你熟悉3d深度排序,请随时发表评论)
答案 0 :(得分:1)
您应该使用外部Comparator
进行比较,而不是尝试实现Comparable
,对于复杂对象而言,这几乎总是错误的做法。
Comparable
适用于具有单个或极少数属性的对象,在所有情况下都需要相同。就像一个ID
的复杂对象是唯一的,它是唯一被比较的东西。
对于在所有情况下都不考虑所有属性的复杂情况,不工作。对于那些时候你使用Comparator
或更好的Ordering
from the Guava library,这样你就可以做优雅的链接和合成。
对三角形进行排序也会使这项练习变得微不足道,因为它们永远不会是非平面的,并且只需要少一点进行比较。
答案 1 :(得分:0)
由于传递失败,您的算法将无法满足compareTo contract;您没有定义总排序。考虑三个Extents
p1(0,3)p2(0,1)p3(2,3)
实施者必须确保p1.compareTo(p2) == 0
暗示这一点
所有其他要点sgn(p1.compareTo(p3)) == sgn(p2.compareTo(p3))
。
p1.compareTo(p2)
是0
p1.compareTo(p3)
为0,但p2.compareTo(p3)
为-1。
排序范围的“最佳”方式取决于您对排序列表的确切要求,但您最有可能最终对近端,远端或中心值进行排序。