在等轴测显示器中,以正确的顺序绘制各种大小的框以使其彼此正确地放置在前面或后面是很棘手的。下图显示了一个示例。应该先绘制蓝色框,然后绘制绿色,然后绘制红色。
我们将探索一种简单的解决方案,用于确定绘制给定框的正确顺序。但是首先,我们必须定义盒子的含义。
我们将框定义为轴对齐和不相交的矩形棱柱。再次看一下上面的图1。每个框都平行于x,y和z轴(即轴对齐)。另外,请注意,这些框彼此相邻但不相交。
首先,如果屏幕上没有两个框重叠,那么我们不必担心首先绘制哪个框。这是我们必须执行的第一个测试,我们将在本节中进行探讨。
3D框的轮廓在等轴测图中变成2D六边形,如下所示。我们使用这些轮廓的轮廓来测试重叠。
我们利用了六角形边始终平行于某个轴这一事实。这使我们可以通过检查每个轴上区域的交点来轻松确定六边形是否重叠。我们添加了一个水平轴来提供帮助。
既然我们已经概述了确定两个框是否在屏幕上重叠的概念,我们将填写实现它的必要细节。
将3D框展平为2D六角形的操作涉及摆脱Z坐标。注意,将一个点的Z坐标增加1等同于将X和Y坐标都增加1。因此,我们可以将Z分别添加到X和Y并完全删除Z。下面显示的是执行此转换的功能的源代码。
//将3D空间位置转换为2D等距位置。 function spaceToIso(spacePos){//新的XY位置仅将Z添加到X和Y。var isoX = spacePos.x + spacePos.z; var isoY = spacePos.y + spacePos.z; return {x:isoX,y:isoY,//计算距原点的水平距离。 h:(isoX-isoY)* Math.cos(Math.PI / 6),//计算距原点的垂直距离。 v:(isoX + isoY)/ 2; }; }最后,在确定每个六边形的边界之后,我们可以使用下面的源代码确定它们是否重叠。
函数doHexagonsOverlap(hex1,hex2){//当且仅当所有轴区域都重叠时,六边形才重叠。 return(//测试x个区域是否相交!(hex1.xmin> = hex2.xmax || hex2.xmin> = hex1.xmax)&& //测试y个区域是否相交!(hex1.ymin > = hex2.ymax || hex2.ymin> = hex1.ymax)&& //测试h区域是否相交!(hex1.hmin> = hex2.hmax || hex2.hmin> = hex1 .hmax)); }现在,我们已经确定了两个框在屏幕上是否重叠,我们可以开始研究如何确定哪个框在另一个框的前面。
回想一下,我们的盒子彼此不相交。我们可以将它们的分离可视化为它们之间的一个薄平面(请参见下面的图5)。识别此平面后,我们可以通过选择该平面正确一侧的框来确定哪个框在前面。
我们可以通过分别查看每个轴来找到分离平面。特别是,我们寻找的轴具有不相交的框范围(请参见下面的图6)。
在上面的图6中,我们选择了一个坐标系,该坐标系使x和y的值较小,以更接近相机。尽管未显示,但z轴在向上方向上为正,因此较大的值使其更接近于相机。
以下是用于确定第一个块是否位于第二个块前面的javascript函数:
函数isBoxInFront(box1,box2){//测试交点x轴//(x的下限值在前面)if(box1.xmin> = box2.xmax){返回false; }否则,如果(box2.xmin> = box1.xmax){返回true; } //测试交点y轴//(y的下限值在前面)if(box1.ymin> = box2.ymax){返回false; }否则,如果(box2.ymin> = box1.ymax){返回true; } //测试相交的z轴// //(更高的z值在前面)if(box1.zmin> = box2.zmax){返回true; }否则,如果(box2.zmin> = box1.zmax){返回false;通常,在绘制框后面的所有框之前,都不应绘制框。因此,我们首先绘制在其后面没有任何框的框,然后我们可以绘制仅在已绘制框之前的框。此过程将继续进行,直到绘制了所有框。 (有关示例,请参见下面的图4。)
要实现此算法,每个盒子都必须确切知道背后有哪些盒子。在上一节中,我们已经确定了如何执行此操作。必须实施搜索,以便每个框后面都有一个框列表。
现在,您已经掌握了以正确的顺序渲染等轴测框所需的全部知识。
下图可能会出现这种情况。前面提到的绘制方法要求我们首先绘制没有任何框的框,但是此示例说明了无法执行此操作的情况。
上图通过将橙色框分成两部分作弊,这是打破这种循环的一种方法。
附录中提到了用于检测此类循环的正式方法。在检测到一个周期后,可以在该周期中的块上绘制特殊的剪切区域,以尊重前框或分割一个或多个会破坏该周期的块。这些是随着我的实验进展将探索和更新本文的解决方案。
对于那些感兴趣的人,我们确定六边形和盒子是否重叠的方法是超平面分离定理的结果。
同样,我们确定盒子的绘制顺序的方法在图论中也被称为拓扑排序