在 SceneKit 中绘制 3D 圆弧和螺旋线
Drawing a 3D arc and helix in SceneKit
这里最近的一个问题让我又想起了SceneKit,想起了一个一直没解决的问题
我的应用程序使用 SK 显示天线设计。大多数天线使用金属杆和网状反射器,所以我使用 SCNCylinder 作为杆,SCNPlane 作为反射器,SCNFloor 作为地面。整个过程花了几个小时,而我 完全是 3D 菜鸟。
但是有些天线使用弯曲成弧形或螺旋形的电线,我在这里用平底船并使用几个首尾相连的圆柱体制作了蹩脚的分段物体。看起来棒极了。
理想情况下,我想要一个单一的对象来呈现具有圆柱形横截面的圆弧或螺旋线。基本上是 SCNTorus,但有开始和结束角度。 谈到在 SK 中使用 UIBezierPath,但它使用 extrude
来生成类似带状的形状。有没有办法做一些类似的事情,但有一个圆柱横截面(比如部分 SCNTorus)?
我知道我可以通过创建顶点(和法线等)来制作自定义形状,但我希望我错过了一个更简单的解决方案。
以下是一些可能有用的起点。
一种方法是使用更多的圆柱体并使它们更短。这与 SCNGeometry 基元上的各种 segmentCount
属性背后的想法相同。我们可以看到当前链接圆柱体版本的屏幕截图吗?
如果您增加 heightSegmentCount
,您可以使用此处概述的方法:。
我刚刚看了一下SCNShape。我在想你可以使用着色器修改器将挤出的形状扭曲成圆形横截面。但是 SCNShape 似乎没有公开段数 属性,我认为您需要创建足够的挤压段以获得良好的外观。 chamferRadius
和 chamferProfile
属性看起来很有趣。我想知道你是否可以使用它们来创建看起来不错的挤压。
您可以用 SCNShape
完成的弧线。从我的其他答案中的技术开始,以获得挤压的 ribbon-like 弧。您需要确保您的路径追溯回自身的部分偏移与挤压深度相同的距离,因此您最终会得到一个横截面为正方形的形状。
要使其横截面呈圆形,请使用 chamferProfile
属性 — 给它一个四分之一圆的路径,并将倒角半径设置为挤压深度的一半,以及四个quarter-circle 倒角会相交,形成圆形横截面。
螺旋是另一回事。 SCNShape
采用平面路径 - 仅在两个维度上变化的路径 - 并将其挤压成 three-dimensional 实体。螺旋是开始时在三个维度上变化的路径。 SceneKit 没有任何用这种术语描述形状的东西,所以这里没有超级简单的答案。
@HalMueller 提到的着色器修改器解决方案很有趣,但存在问题。在几何体入口点使用修改器来进行简单的弯曲很简单——比如说,将每个 y 坐标偏移一定量,甚至偏移量是原因的函数。但那是一个 one-dimensional 变换,所以你不能用它来把电线绕在自己身上。 (它也改变了横截面。)最重要的是,着色器修改器在渲染时发生在 GPU 上,所以它们的效果是一种幻觉:SceneKit 模型中的“真实”几何体仍然是一个圆柱体,所以像命中测试这样的功能适用于那个而不是转换后的几何体。
制作类似螺旋线的最佳解决方案可能是自定义几何体 — 生成您自己的顶点数据 (SCNGeometrySource
)。如果您按照该形状的 definition. To wrap a cross section around it, follow the Frenet formulas 在螺旋上的每个点创建一个局部坐标系,则在螺旋上找到一组点的数学运算非常简单。然后创建一个索引缓冲区 (SCNGeometryElement
) 以将所有这些点缝合到具有三角形或三条带的表面中。 (好的,hand-waving 围绕一个很深的主题做了很多,但是完整的教程对于 SO 答案来说太大了。不过,这应该足以作为入门的面包屑...)
这里最近的一个问题让我又想起了SceneKit,想起了一个一直没解决的问题
我的应用程序使用 SK 显示天线设计。大多数天线使用金属杆和网状反射器,所以我使用 SCNCylinder 作为杆,SCNPlane 作为反射器,SCNFloor 作为地面。整个过程花了几个小时,而我 完全是 3D 菜鸟。
但是有些天线使用弯曲成弧形或螺旋形的电线,我在这里用平底船并使用几个首尾相连的圆柱体制作了蹩脚的分段物体。看起来棒极了。
理想情况下,我想要一个单一的对象来呈现具有圆柱形横截面的圆弧或螺旋线。基本上是 SCNTorus,但有开始和结束角度。 extrude
来生成类似带状的形状。有没有办法做一些类似的事情,但有一个圆柱横截面(比如部分 SCNTorus)?
我知道我可以通过创建顶点(和法线等)来制作自定义形状,但我希望我错过了一个更简单的解决方案。
以下是一些可能有用的起点。
一种方法是使用更多的圆柱体并使它们更短。这与 SCNGeometry 基元上的各种 segmentCount
属性背后的想法相同。我们可以看到当前链接圆柱体版本的屏幕截图吗?
如果您增加 heightSegmentCount
,您可以使用此处概述的方法:
我刚刚看了一下SCNShape。我在想你可以使用着色器修改器将挤出的形状扭曲成圆形横截面。但是 SCNShape 似乎没有公开段数 属性,我认为您需要创建足够的挤压段以获得良好的外观。 chamferRadius
和 chamferProfile
属性看起来很有趣。我想知道你是否可以使用它们来创建看起来不错的挤压。
您可以用 SCNShape
完成的弧线。从我的其他答案中的技术开始,以获得挤压的 ribbon-like 弧。您需要确保您的路径追溯回自身的部分偏移与挤压深度相同的距离,因此您最终会得到一个横截面为正方形的形状。
要使其横截面呈圆形,请使用 chamferProfile
属性 — 给它一个四分之一圆的路径,并将倒角半径设置为挤压深度的一半,以及四个quarter-circle 倒角会相交,形成圆形横截面。
螺旋是另一回事。 SCNShape
采用平面路径 - 仅在两个维度上变化的路径 - 并将其挤压成 three-dimensional 实体。螺旋是开始时在三个维度上变化的路径。 SceneKit 没有任何用这种术语描述形状的东西,所以这里没有超级简单的答案。
@HalMueller 提到的着色器修改器解决方案很有趣,但存在问题。在几何体入口点使用修改器来进行简单的弯曲很简单——比如说,将每个 y 坐标偏移一定量,甚至偏移量是原因的函数。但那是一个 one-dimensional 变换,所以你不能用它来把电线绕在自己身上。 (它也改变了横截面。)最重要的是,着色器修改器在渲染时发生在 GPU 上,所以它们的效果是一种幻觉:SceneKit 模型中的“真实”几何体仍然是一个圆柱体,所以像命中测试这样的功能适用于那个而不是转换后的几何体。
制作类似螺旋线的最佳解决方案可能是自定义几何体 — 生成您自己的顶点数据 (SCNGeometrySource
)。如果您按照该形状的 definition. To wrap a cross section around it, follow the Frenet formulas 在螺旋上的每个点创建一个局部坐标系,则在螺旋上找到一组点的数学运算非常简单。然后创建一个索引缓冲区 (SCNGeometryElement
) 以将所有这些点缝合到具有三角形或三条带的表面中。 (好的,hand-waving 围绕一个很深的主题做了很多,但是完整的教程对于 SO 答案来说太大了。不过,这应该足以作为入门的面包屑...)