简体   繁体   中英

UIBezierPath Quadratic Curve is a Straight Line

I'm trying to create a curved arrow for displaying in ab ARKit scene, however, the curvature of the arrow staff is just rendering as a straight line on both sides.

func createTurnArrow(_ direction: Direction) -> SCNShape {
    let path = UIBezierPath()
    path.move(to: CGPoint(x: 0.2, y: 0)) // A
    path.addLine(to: CGPoint(x: 0, y: 0.2)) // B
    path.addLine(to: CGPoint(x: 0, y: 0.1)) // C
    path.addQuadCurve(to: CGPoint(x: -0.3, y: -0.3), controlPoint: CGPoint(x: -0.3, y: 0.1)) // Curve 1
    path.addLine(to: CGPoint(x: -0.1, y: -0.3)) // D
    path.addQuadCurve(to: CGPoint(x: 0, y: -0.1), controlPoint: CGPoint(x: -0.1, y: -0.1)) // Curve 2
    path.addLine(to: CGPoint(x: 0, y: -0.2)) // E
    path.close()

    return direction == .left ?
      SCNShape(path: path.reversing(), extrusionDepth: self.defaultDepth) :
      SCNShape(path: path, extrusionDepth: self.defaultDepth)
}

My intuition tells me that create a node with this function:

SCNNode(geometry: createTurnArrow(.right))

should produce a shape like this:

在此处输入图片说明

but instead renders this without any curves to the tail of the arrow:

在此处输入图片说明

I've tried a bunch of other math to get the current control points for the quadratic curves but nothing is worry. Any ideas?

EDIT:

Where is the schematic with plotted points and my assumption of how this should be rendered with the curves.

在此处输入图片说明

Read the SCNShape path documentation . It says this:

The path's flatness (see flatness in NSBezierPath ) determines the level of detail SceneKit uses in building a three-dimensional shape from the path—a larger flatness value results in fewer polygons to render, increasing performance.

(Since you're on iOS, substitute UIBezierPath for NSBezierPath .)

What is the default flatness of a UIBezierPath ? Here's what the documentation says:

The flatness value measures the largest permissible distance (measured in pixels) between a point on the true curve and a point on the rendered curve. Smaller values result in smoother curves but require more computation time. Larger values result in more jagged curves but are rendered much faster. The default flatness value is 0.6.

Now compare the default flatness (0.6) to the overall size of your shape (0.5 × 0.5). Notice that the flatness is bigger than the size of your shape! So each of your curves is getting flattened to a single straight line.

Change the flatness of your path to something more appropriate for your shape, or change the scale of your shape to something more appropriate for the default flatness.

let path = UIBezierPath()
path.flatness = 0.05 // <----------------------- insert this statement
path.move(to: CGPoint(x: 0.2, y: 0)) // A
path.addLine(to: CGPoint(x: 0, y: 0.2)) // B
// etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM