Graphics 如何对犹他茶壶进行空间分割?

Graphics 如何对犹他茶壶进行空间分割?,graphics,3d,postscript,space-partitioning,Graphics,3d,Postscript,Space Partitioning,处理完之后,我需要进行二进制空间划分,以便使用画家的算法绘制投影三角形 我已经实现了很多 但它正在做一棵查理·布朗树!也就是说,大多数节点都有一个分支完全为空。整个策略都是错误的。由于茶壶本质上是球形的,所以整个形状仅位于任何特定组件三角形的一侧 所以我想我需要更像苹果取芯器的分区平面:所有的分区平面都穿过y轴。但我有点不守规矩了,你知道吗分割茶壶的最佳方法是什么? 这是我的bsp树生成器。它使用链接问题中发布的其他功能 编辑:额外的杂耍,以避免溢出。完整的程序可用(需要和)。数值输出显示正在构

处理完之后,我需要进行二进制空间划分,以便使用画家的算法绘制投影三角形

我已经实现了很多

但它正在做一棵查理·布朗树!也就是说,大多数节点都有一个分支完全为空。整个策略都是错误的。由于茶壶本质上是球形的,所以整个形状仅位于任何特定组件三角形的一侧

所以我想我需要更像苹果取芯器的分区平面:所有的分区平面都穿过y轴。但我有点不守规矩了,你知道吗分割茶壶的最佳方法是什么?

这是我的bsp树生成器。它使用链接问题中发布的其他功能

编辑:额外的杂耍,以避免溢出。完整的程序可用(需要和)。数值输出显示正在构造的树节点的深度

% helper functions to insert and remove triangles in lists
/unshift { % [ e1 .. eN ] e0  .  [ e0 e1 .. eN ]
    exch aload length 1 add array astore
} def
/shift { % [ e0 e1 .. eN ]  .  [ e1 .. eN ] e0
    aload length 1 sub array astore exch
} def


/makebsp { % [ triangles ]  .  bsptree
    count =
%5 dict  %This is the tree node data structure
<</P[]/PM[]/plane[]/front[]/behind[]/F<<>>/B<<>>>>
begin

    dup length 1 le{ % If 0 or 1 triangles
        dup length 0 eq { % If 0 triangles
            pop           %    discard
        }{                % If 1 triangle
            aload pop /P exch def  % put triangle in tree node
        }ifelse
    }{ % length>1

    shift /P exch def  % P: Partitioning Polygon (triangle)
    P transpose aload pop
    [1 1 1] 4 array astore % make column vectors of homogeneous coords
    /PM exch def

    [ % Compute equation of the plane defined by P
      PM 0 3 getinterval det
      [ PM 0 get PM 2 get PM 3 get ] det
      [ PM 0 get PM 1 get PM 3 get ] det
      PM 1 3 getinterval det 3 mul
    ] /plane exch def

    % iterate through remaining triangles, testing against plane, adding to lists
    /front [] def
    /behind [] def
    { %forall  [P4 P5 P6] = [[x4 y4 z4][x5 y5 z5][x6 y6 z6]]
        /T exch def
        T transpose % [[x4 x5 x6][y4 y5 y6][z4 z5 z6]]
        {aload pop add add} forall % (x4+x5+x6) (y4+y5+y6) (z4+z5+z6)

        plane 2 get mul 3 1 roll % z|C| (x) (y)
        plane 1 get mul 3 1 roll % y|B| z|C| (x)
        plane 0 get mul          % y|B| z|C| x|A|
        plane 3 get add add add  % Ax+By+Cz+D

        0 le { /front front
        }{ /behind behind
        } ifelse
        T unshift def
    } forall

    %front == ()= behind == flush (%lineedit)(r)file pop

    % recursively build F and B nodes from front and behind lists
    %/F front makebsp def
    front currentdict end exch
        makebsp
    exch begin /F exch def
    %/B behind makebsp def
    behind currentdict end exch
        makebsp
    exch begin /B exch def
    /front [] def
    /behind [] def

    } ifelse
currentdict end
} def
%helper函数用于在列表中插入和删除三角形
/取消移位{%[e1..eN]e0.[e0 e1..eN]
exch aload长度1添加数组astore
}def
/移位{%[e0 e1..eN].[e1..eN]e0
aload长度1子阵列astore exch
}def
/makebsp{%[三角形].bsptree
计数=
%5 dict%这是树节点数据结构
开始
dup长度1 le{%如果0或1个三角形
dup长度0 eq{%If 0三角形
弹出百分比丢弃
}{%如果1个三角形
aload pop/P exch def%将三角形放入树节点
}如果有
}{%length>1
shift/P exch def%P:分区多边形(三角形)
P转置aload pop
[1]4个数组中有%make齐次坐标的列向量
/PM exch def
[%P定义的平面的计算公式
下午0时3分
[PM 0获取PM 2获取PM 3获取]det
[PM 0获取PM 1获取PM 3获取]det
下午1:3获取间隔det 3 mul
]/plane exch def
%迭代剩余的三角形,根据平面进行测试,添加到列表中
/前[]定义
/在[]def后面
{%forall[P4 P5 P6]=[[x4 y4 z4][x5 y5 z5][x6 y6 z6]]
/T exch def
T转置%[[x4x5x6][y4y5y6][z4z5z6]]
{aload pop add add}forall%(x4+x5+x6)(y4+y5+y6)(z4+z5+z6)
飞机2获得mul 3 1滚转%z | C |(x)(y)
飞机1获得mul 3 1滚转%y | B | z | C |(x)
平面0获得多个%y | B | z | C | x | A|
平面3获取添加%Ax+By+Cz+D
0乐{/前
}{/后面
}如果有
T取消移动def
}福尔
%前==()=后==刷新(%lineedit)(r)文件弹出
%从前面和后面的列表递归地构建F和B节点
%/F前makebsp def
前电流输入端exch
makebsp
exch begin/F exch def
%/B在makebsp def后面
在当前DICT end exch后面
makebsp
exch begin/B exch def
/前[]定义
/在[]def后面
}如果有
电流记录端
}def
输出:

BSP是为类似地震的游戏中的关卡等几何图形而发明的,可能很难用于某些特定的几何图形集。BSP使用一个现有的三角形来分割标高,所以想象一下,当您想在球体上使用它时,它的行为会是怎样的

对于茶壶,使用八叉树可以获得更好的结果,它不需要沿现有三角形分割几何体。但我不确定它与Painter算法的配合效果如何


如果你真的需要在这里使用BSP树,那么你应该仔细挑选你的三角形。我不理解你所有的代码,但我看不到这一部分。只需迭代当前树分支中的所有三角形,并为每个三角形计算前面和后面的三角形数。前三角形和后三角形数量相似的一个通常是用作拆分平面的最佳平面。

我没有完全做八叉树,但我修改了bsp树生成器,使用一个明确的平面列表,我用轴对齐的平面填充该列表,切割空间-4
/planelist [
    0 .2 4 { /x exch def
        [ 1 0 0 x ]
        [ 1 0 0 x neg ]
        [ 0 1 0 x ]
        [ 0 1 0 x neg ]
        [ 0 0 1 x ]
        [ 0 0 1 x neg ]
    } for
] def

Postscript程序可用(需要)

浅绿色工件是bsp构建期间显示的“预览”的结果。一旦建立,后续页面(图像)绘制迅速,没有人为的相机围绕茶壶旋转

主体与喷口和手柄的连接(未从该角度显示)仍然需要工作


由于bsp的性能更好,因此不必严格执行背面剔除。但是它使预览效果更好。

另一种改进此图像BSP的方法是使用层次分解。茶壶不仅仅是一堆贝塞尔曲面,它有一些曲面描述身体,还有一些曲面描述把手、壶嘴、壶盖(、壶底?)


因此,树的前几层应该是顶层。把手在身体的前面还是后面?喷口在身体前面吗?这些问题的答案将是画家算法的有用指南。

我想它不必是BSP。这似乎是第一件显而易见的尝试。我只需要在绘图时隐藏隐藏的曲面(postscript没有Z缓冲区)。我将尝试使用“在每个节点上搜索”的方法。但这可能需要一些时间。我很惊讶这棵树能这么快工作。BSP被许多光线跟踪引擎使用。它们不像游戏引擎BSP那样工作。他们所做的是将数据集拆分为2,然后交换基数方向。首先在X,Y,Z上进行拆分。最终的结果是一个稍微好一点的平衡八叉树结构。我使用BSPs做了类似的事情来进行分析隐藏线渲染,这与您的尝试类似。无论如何,实现背面剔除需要的东西,因为你不需要担心这些脸。实际上,你不需要z缓冲区或painters算法