SceneKit:如何创建带有不同圆角半径的圆角立方体?
实现SceneKit中各边缘圆角不同的立方体
嘿,我完全懂你的需求——SCNBox自带的chamferRadius确实只能给所有边缘套上一样的圆角,没法实现你想要的差异化效果。不过有几个实用的方案能帮你搞定这个问题,我给你拆解一下:
方案一:用布尔运算组合几何体(快速上手)
这个方法不用写复杂的顶点计算代码,靠SceneKit的布尔运算就能拼出想要的效果,适合快速原型开发。思路是:先做一个无倒角的基础立方体,然后在需要大圆角的角落/边缘位置,放置对应大小的球体或圆柱体,通过布尔合并(union)把它们和基础立方体融合,或者用布尔减法(difference)切掉直角部分。
举个Swift代码例子:
// 1. 创建基础立方体(尺寸要预留出圆角的空间) let finalSize: CGFloat = 2.0 let corner1Radius: CGFloat = 0.5 let corner2Radius: CGFloat = 0.2 // 基础立方体的尺寸 = 最终尺寸 - 2*最大圆角半径 let baseSize = finalSize - 2 * corner1Radius let baseBox = SCNBox(width: baseSize, height: baseSize, length: baseSize, chamferRadius: 0) let baseNode = SCNNode(geometry: baseBox) // 2. 创建第一个角落的圆角球体(半径0.5) let sphere1 = SCNSphere(radius: corner1Radius) let sphereNode1 = SCNNode(geometry: sphere1) // 球体位置要对应基础立方体的角落 sphereNode1.position = SCNVector3(baseSize/2, baseSize/2, baseSize/2) // 3. 创建第二个角落的圆角球体(半径0.2) let sphere2 = SCNSphere(radius: corner2Radius) let sphereNode2 = SCNNode(geometry: sphere2) sphereNode2.position = SCNVector3(-baseSize/2, -baseSize/2, -baseSize/2) // 4. 执行布尔合并,把基础立方体和球体融合 if let combinedWithSphere1 = baseBox.union(with: sphere1), let finalGeometry = combinedWithSphere1.union(with: sphere2) { let finalNode = SCNNode(geometry: finalGeometry) scene.rootNode.addChildNode(finalNode) }
注意:布尔运算需要iOS 11+/macOS 10.13+支持,而且要根据圆角半径调整基础立方体的尺寸和球体位置,避免出现错位或多余的面。
方案二:自定义SCNGeometry(精准控制)
如果你需要绝对精准的效果,或者要做更复杂的边缘差异化,就需要手动构建几何体的顶点、法线和三角面。这个方法需要一点图形学基础,核心思路是:
- 为每个边缘计算对应的圆弧顶点
- 把平面部分和圆弧部分的顶点组合起来
- 用
SCNGeometrySource和SCNGeometryElement封装成自定义几何体
举个简化的思路(具体顶点计算需要根据你的圆角需求调整):
// 示例:创建一个带不同圆角的矩形面,再拉伸成立方体 let path = UIBezierPath() // 绘制带不同圆角的矩形:比如左上角半径0.5,右下角半径0.2 path.move(to: CGPoint(x: finalSize/2, y: finalSize/2 - 0.5)) path.addArc(withCenter: CGPoint(x: finalSize/2 - 0.5, y: finalSize/2 - 0.5), radius: 0.5, startAngle: 0, endAngle: .pi/2, clockwise: false) // 继续绘制其他边和不同的圆弧... // 把路径拉伸成立方体的一个面 let extrusionGeo = SCNExtrusionGeometry(bezierPath: path, depth: finalSize, extrusionDepth: 0) // 重复这个过程创建其他5个面,调整位置和法线后组合成完整立方体
方案三:用3D建模软件导出模型(最省心)
如果你不想折腾代码,直接用Blender、SketchUp这类3D建模软件,可视化地给立方体的每个边缘设置不同的圆角半径,然后导出成DAE或USDZ格式,再导入到SceneKit里使用就行:
- 建模软件里轻松调整每个边缘的圆角参数
- 导入后用
SCNScene(named: "CustomBox.dae")加载,提取对应的节点添加到场景中
这个方法适合快速实现复杂的造型,不用写任何图形学相关的代码。
内容的提问来源于stack exchange,提问作者Semyon Tikhonenko




