You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Swift在SceneKit中程序化绘制半球体?

问题原因:你误解了SCNShape的作用

你的代码里用UIBezierPath(ovalIn:)创建了一个椭圆,然后通过SCNShape的extrusionDepth把它拉伸成了一个扁的椭圆柱——这是因为SCNShape的核心是把2D路径沿着垂直平面的方向"挤压"成棱柱体,而不是把路径绕轴旋转成回转体(比如半球这种)。所以自然得不到你想要的半球效果。

两种简单的解决方案

方案1:用SCNLatheGeometry(推荐,最直接生成半球)

SCNLatheGeometry专门用来把2D路径绕指定轴旋转成3D回转体,刚好适合做半球。你只需要创建一个半圆的贝塞尔路径,让它绕Y轴旋转即可:

// 1. 创建半圆的贝塞尔路径(半径0.2,对应你原来椭圆的半宽/半高)
let halfCirclePath = UIBezierPath()
halfCirclePath.addArc(
    withCenter: CGPoint(x: 0, y: 0),
    radius: 0.2,
    startAngle: .pi,  // 从π弧度(180度)开始
    endAngle: 0,      // 到0弧度(0度)结束
    clockwise: false  // 逆时针绘制,得到上半圆
)
// 闭合路径,确保Lathe能生成完整的几何体
halfCirclePath.addLine(to: CGPoint(x: 0, y: 0))
halfCirclePath.close()

// 2. 用半圆路径生成半球几何体
let hemisphereGeometry = SCNLatheGeometry(path: halfCirclePath)
// 调整径向分段数,数值越高半球表面越平滑(默认是16,这里设32更细腻)
hemisphereGeometry.radialSegmentCount = 32

// 3. 创建节点并添加到场景
let hemisphereNode = SCNNode(geometry: hemisphereGeometry)
// 如果你需要调整位置/旋转,直接修改节点属性即可
// hemisphereNode.position = SCNVector3(0, 0.1, 0)
scene.rootNode.addChildNode(hemisphereNode)

方案2:用SCNSphere裁剪出半球

如果你更习惯用球体,也可以先创建完整球体,再通过裁剪平面只保留上半部分:

// 1. 创建完整球体(半径0.2,和方案1一致)
let sphere = SCNSphere(radius: 0.2)
sphere.segmentCount = 32  // 保证表面平滑

// 2. 创建裁剪平面:剔除Y轴负方向的部分
let clipPlane = SCNClipPlane()
clipPlane.plane = SCNPlane(width: 0.5, height: 0.5)
clipPlane.plane.firstMaterial?.diffuse.contents = UIColor.clear  // 裁剪平面透明
clipPlane.position = SCNVector3(0, 0, 0)  // 裁剪平面位于原点
clipPlane.normal = SCNVector3(0, -1, 0)  // 法线向下,只保留法线另一侧(Y正方向)的部分

// 3. 创建球体节点并启用裁剪
let hemisphereNode = SCNNode(geometry: sphere)
hemisphereNode.clipsToPlanes = true
hemisphereNode.clipPlanes = [clipPlane]
scene.rootNode.addChildNode(hemisphereNode)

额外提示

如果非要用SCNShape实现,其实并不合适——它的设计初衷是生成棱柱类的3D模型,而非曲面回转体。强行用它做半球需要复杂的路径组合和节点变换,效果还不如上面两种方案自然。

内容的提问来源于stack exchange,提问作者Krishnan Anantha Narayanan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:29:00