4

I'd like to draw a bezier curved line with SceneKit and thought this would work:

func drawCurvedLine() {

    let scene = SCNScene()
    let scnView = self.view as! SCNView
    scnView.scene = scene
    scnView.allowsCameraControl = true

    let path = UIBezierPath()
    path.moveToPoint(CGPoint(x: -20, y: -20))
    path.addCurveToPoint(CGPoint(x: 20, y: 20),
        controlPoint1: CGPoint(x: 5, y: 5),
        controlPoint2: CGPoint(x: 15, y: 15))

    path.closePath()

    path.flatness = 0.3

    var scnShape:SCNShape = SCNShape(path: path, extrusionDepth: 2)

    scnShape.firstMaterial?.diffuse.contents = UIColor.purpleColor()
    let shapeNode = SCNNode(geometry: scnShape)
    scene.rootNode.addChildNode(shapeNode)
}

However my results are like this screenshot:SceneKit render

Does anyone know why the curveTo control points are ignored or how to switch them on? Or any other method to draw a curved line in SceneKit?

  • Edit Updating the path coordinates to:

    path.moveToPoint(CGPoint(x: -20, y: -20)) path.addCurveToPoint(CGPoint(x: 20, y: 20), controlPoint1: CGPoint(x: 10, y: 0), controlPoint2: CGPoint(x: 10, y: 0))

I can get this:curved

However I guess I'm looking to NOT fill the shape. Ideally a curved tubular line is what I'm trying to achieve here. ( Imagine a power cable or some such ... ). I guess I would love to have the equivalent of SCNLine or SCNTube "render on bezier path"

dijipiji
  • 3,063
  • 1
  • 26
  • 21
  • Ok, so to make it more of a line-shape, try translating all the points along an arbitrary axis. `path.moveToPoint(CGPoint(x: -20, y: -20))` `path.addCurveToPoint(CGPoint(x: 20, y: 20), controlPoint1: CGPoint(x: 10, y: 0), controlPoint2: CGPoint(x: 10, y: 0))` (original points) Then: `path.moveToPoint(CGPoint(x: 20, y: -17))` `path.addCurveToPoint(CGPoint(x: -20, y: -17), controlPoint1: CGPoint(x: 10, y: 0), controlPoint2: CGPoint(x: 10, y: 3))` (added 3 to all y values). Look into Chamfering the `SCNShape` and using `SCNLight` of type `SCNLightTypeOmni` or `SCNLightTypeDirectional`. – jperl Jun 25 '15 at 13:29

2 Answers2

3

SCNShape just be built from closed Bézier paths and will always be filled (with the exception of holes). These paths can be completely custom but will always be extruded along a segment along the z axis. What you want is to extrude a circle along an arbitrary path, and that's not supported.

SCNGeometry exposes APIs that allow you to build arbitrary geometries.

mnuages
  • 13,049
  • 2
  • 23
  • 40
2

It is working! Very well, I might add.

The problem is, all your points lie on the same line, y=x

Try changing your control points to have values where y!=x

ex,

    path.addCurveToPoint(CGPoint(x: 20, y: 20),
    controlPoint1: CGPoint(x: 15, y: 0),
    controlPoint2: CGPoint(x: 20, y: 10))
jperl
  • 1,066
  • 7
  • 14