You can’t recolor arbitrary parts of SCNCylinder
with discrete materials. SceneKit defines only one way to decompose a cylinder into separate portions with separate materials (from the 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
.
That means you can set your planet.materials
to an array of three materials, but SceneKit can only use them to color the top, bottom, and sides separately.
So what recourse do you have if you want to create a pie-chart style appearance? OTOH, I can think of two or three directions to investigate:
Do it with images
You mention you’ve already tried something like this — create a static image that looks like a pie chart and assign it to the (top material?) of the cylinder.
There’s nothing preventing you from extending this technique to non-static pie charts. You’ll just need to create your images dynamically (with CoreGraphics, UIGraphicsImageRenderer, etc).
To get your pie chart looking right in 3D you’ll need to create 3 images — a regular pie chart for the top of the cylinder, a reversed version of the same pie chart for the bottom, and a rectangular image with top-to-bottom blocks of color in the same relative proportions as the pie slices that wraps around the sides. It’ll probably take some experimentation to figure out how to format those three images so they line up right.
Do it with custom geometry
If you want a “fully 3D” pie chart (like the ones you see in Pages, Numbers, and Keynote), where each slice is a separate 3D object that can be pulled away from the pie made taller/shorter than other slices, etc, then SCNCylinder
is not for you. It only knows how to draw complete cylinders.
There aren’t any built-in SceneKit classes for creating wedge shapes, but if you can work out the math to construct a mesh yourself, you can use SCNGeometrySource
and SCNGeometryElement
to construct that mesh in SceneKit.
Do it with SCNShape
Custom geometry might be overkill for this task, though. The kind of shape you’re looking for is one of the simpler kinds of 3D geometry — a 2D shape (a sector of a circle) extruded in a third dimension to create a 3D solid (a wedge of a pie, slice of a cake, or whatever other delicious metaphor you prefer).
In SceneKit, there’s an app for that. (Er, a 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.
So, to build a pie chart:
Create several UIBezierPath
objects, one for each slice of pie, using the init(arcCenter:radius:startAngle:endAngle:clockwise:)
initializer. Use the same center point for all of them (zero is probably fine).
From each Bézier path, create an SCNShape
with your preferred extrusion depth. If you want each slice of your pie to have a different flavor color, assign a different material to each shape.
Assemble the slices into a pie by creating an SCNNode
to hold each, and placing those nodes at the same position. (The 2D origin of the arc is respected in the 3D coordinate system, so if you set the same node position for different arcs created with the same center they’ll have the same center in 3D.) If you want to be able to move the whole pie together after that, create another SCNNode
and make all of the slices its children.
Dangit, now I’m hungry...