ARKit:如何在 SCNView 中为 SCNCylinder 应用多种颜色的 material?
ARKit : How to apply material with multiple colors for SCNCylinder in SCNView?
我必须使 SCNCylinder 看起来像动态饼图,我可以通过使用以下代码向 SCNCylinder 添加纹理或应用颜色来使其看起来像静态饼图。但是,我的饼图值随机变化,想要添加 material 颜色值占据圆柱体的百分比部分。
var planet : SCNGeometry
planet = SCNCylinder(radius: 0.2, height: 0.05)
let material = SCNMaterial()
material.diffuse.contents = UIImage(named: "texture.jpg")
//OR to apply single color
material.diffuse.contents = UIColor.red
planet.materials = [material]
let planetNode = SCNNode(geometry: planet)
你不能用离散的 material 重新着色 SCNCylinder
的任意部分。 SceneKit 仅定义了一种将圆柱体分解为具有单独 material 的单独部分的方法(来自 docs):
A cylinder contains three SCNGeometryElement
objects: one each for its base and top, and one that wraps around its sides. SceneKit can render each element using a different material. For details, see the materials
property in SCNGeometry
.
这意味着您可以将 planet.materials
设置为三个 material 的数组,但 SceneKit 只能使用它们分别为顶部、底部和侧面着色。
那么如果你想创建饼图样式的外观,你有什么办法? OTOH,我可以想到两个或三个方向进行调查:
用图片做
你提到你已经尝试过这样的事情——创建一个看起来像饼图的静态图像并将其分配给圆柱体的(顶部material?)。
没有什么能阻止您将此技术扩展到非静态饼图。您只需要动态创建图像(使用 CoreGraphics、UIGraphicsImageRenderer 等)。
要使您的饼图在 3D 中看起来正确,您需要创建 3 个图像 - 圆柱顶部的常规饼图、底部相同饼图的反转版本以及矩形图像从上到下的颜色块与环绕两侧的饼图块具有相同的相对比例。可能需要进行一些实验才能弄清楚如何设置这三张图片的格式以使它们正确排列。
使用自定义几何体
如果您想要一个“全 3D”饼图(就像您在 Pages、Numbers 和 Keynote 中看到的那样),其中每个切片都是一个单独的 3D 对象,可以从制作的饼中拉出 taller/shorter 比其他切片等,那么 SCNCylinder
不适合你。它只知道如何绘制完整的圆柱体。
没有任何用于创建楔形的内置 SceneKit classes,但是如果您可以自己计算数学来构建网格,则可以使用 SCNGeometrySource
and SCNGeometryElement
来构建它SceneKit 中的网格。
用SCNShape
做
不过,自定义几何图形对于这项任务来说可能有点过分了。您正在寻找的形状类型是一种更简单的 3D 几何形状 - 二维形状(圆的一个扇区)在三维空间中挤压以创建 3D 实体(饼的楔形、蛋糕的切片) ,或您喜欢的任何其他美味比喻)。
在 SceneKit 中,有一个应用程序。 (呃,一个class。)SCNShape
takes a 2D UIBezierPath
and extrudes it to create a 3D object. You can even apply nice little rounded edges to it. And UIBezierPath
lets you create paths using circle arcs。
因此,要构建饼图:
使用 init(arcCenter:radius:startAngle:endAngle:clockwise:)
初始值设定项创建多个 UIBezierPath
对象,每个饼图切片一个。对所有这些使用相同的中心点(零可能没问题)。
从每个 Bézier 路径,创建一个 SCNShape
具有您首选的挤压深度。如果您希望每块馅饼都有不同的 风味 颜色,请为每个形状分配不同的 material。
Assemble 通过创建一个 SCNNode
来容纳每个切片,并将这些节点放置在相同的位置,将切片分成饼图。 (圆弧的 2D 原点在 3D 坐标系中受到尊重,因此如果您为使用相同中心创建的不同圆弧设置相同的节点位置,它们将在 3D 中具有相同的中心。)如果您希望能够移动之后将整个馅饼放在一起,创建另一个 SCNNode
并将所有切片作为其子切片。
该死,我现在饿了...
我必须使 SCNCylinder 看起来像动态饼图,我可以通过使用以下代码向 SCNCylinder 添加纹理或应用颜色来使其看起来像静态饼图。但是,我的饼图值随机变化,想要添加 material 颜色值占据圆柱体的百分比部分。
var planet : SCNGeometry
planet = SCNCylinder(radius: 0.2, height: 0.05)
let material = SCNMaterial()
material.diffuse.contents = UIImage(named: "texture.jpg")
//OR to apply single color
material.diffuse.contents = UIColor.red
planet.materials = [material]
let planetNode = SCNNode(geometry: planet)
你不能用离散的 material 重新着色 SCNCylinder
的任意部分。 SceneKit 仅定义了一种将圆柱体分解为具有单独 material 的单独部分的方法(来自 docs):
A cylinder contains three
SCNGeometryElement
objects: one each for its base and top, and one that wraps around its sides. SceneKit can render each element using a different material. For details, see thematerials
property inSCNGeometry
.
这意味着您可以将 planet.materials
设置为三个 material 的数组,但 SceneKit 只能使用它们分别为顶部、底部和侧面着色。
那么如果你想创建饼图样式的外观,你有什么办法? OTOH,我可以想到两个或三个方向进行调查:
用图片做
你提到你已经尝试过这样的事情——创建一个看起来像饼图的静态图像并将其分配给圆柱体的(顶部material?)。
没有什么能阻止您将此技术扩展到非静态饼图。您只需要动态创建图像(使用 CoreGraphics、UIGraphicsImageRenderer 等)。
要使您的饼图在 3D 中看起来正确,您需要创建 3 个图像 - 圆柱顶部的常规饼图、底部相同饼图的反转版本以及矩形图像从上到下的颜色块与环绕两侧的饼图块具有相同的相对比例。可能需要进行一些实验才能弄清楚如何设置这三张图片的格式以使它们正确排列。
使用自定义几何体
如果您想要一个“全 3D”饼图(就像您在 Pages、Numbers 和 Keynote 中看到的那样),其中每个切片都是一个单独的 3D 对象,可以从制作的饼中拉出 taller/shorter 比其他切片等,那么 SCNCylinder
不适合你。它只知道如何绘制完整的圆柱体。
没有任何用于创建楔形的内置 SceneKit classes,但是如果您可以自己计算数学来构建网格,则可以使用 SCNGeometrySource
and SCNGeometryElement
来构建它SceneKit 中的网格。
用SCNShape
做
不过,自定义几何图形对于这项任务来说可能有点过分了。您正在寻找的形状类型是一种更简单的 3D 几何形状 - 二维形状(圆的一个扇区)在三维空间中挤压以创建 3D 实体(饼的楔形、蛋糕的切片) ,或您喜欢的任何其他美味比喻)。
在 SceneKit 中,有一个应用程序。 (呃,一个class。)SCNShape
takes a 2D UIBezierPath
and extrudes it to create a 3D object. You can even apply nice little rounded edges to it. And UIBezierPath
lets you create paths using circle arcs。
因此,要构建饼图:
使用
init(arcCenter:radius:startAngle:endAngle:clockwise:)
初始值设定项创建多个UIBezierPath
对象,每个饼图切片一个。对所有这些使用相同的中心点(零可能没问题)。从每个 Bézier 路径,创建一个
SCNShape
具有您首选的挤压深度。如果您希望每块馅饼都有不同的风味颜色,请为每个形状分配不同的 material。Assemble 通过创建一个
SCNNode
来容纳每个切片,并将这些节点放置在相同的位置,将切片分成饼图。 (圆弧的 2D 原点在 3D 坐标系中受到尊重,因此如果您为使用相同中心创建的不同圆弧设置相同的节点位置,它们将在 3D 中具有相同的中心。)如果您希望能够移动之后将整个馅饼放在一起,创建另一个SCNNode
并将所有切片作为其子切片。
该死,我现在饿了...