SceneKit - Draw 3D Parabola

They give me three points and I need to draw a smooth three-dimensional parabola. The problem is that the curved line is variable and has some strange divots in it

parabola

Here is my code ...

func drawJump(jump: Jump){
    let halfDistance = jump.distance.floatValue/2 as Float
    let tup = CalcParabolaValues(0.0, y1: 0.0, x2: halfDistance, y2: jump.height.floatValue, x3: jump.distance.floatValue, y3: 0)
    println("tuple \tup")

    var currentX = 0 as Float
    var increment = jump.distance.floatValue / Float(50)
    while currentX < jump.distance.floatValue - increment {

        let x1 = Float(currentX)
        let x2 = Float((currentX+increment))
        let y1 = calcParabolaYVal(tup.a, b: tup.b, c: tup.c, x: x1)
        let y2 = calcParabolaYVal(tup.a, b: tup.b, c: tup.c, x: x2)

        drawLine(x1, y1: y1, x2: x2, y2: y2)

        currentX += increment
    }
}

func CalcParabolaValues(x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float) -> (a: Float, b: Float, c: Float) {
    println(x1, y1, x2, y2, x3, y3)
    let a = y1/((x1-x2)*(x1-x3)) + y2/((x2-x1)*(x2-x3)) + y3/((x3-x1)*(x3-x2))
    let b = (-y1*(x2+x3)/((x1-x2)*(x1-x3))-y2*(x1+x3)/((x2-x1)*(x2-x3))-y3*(x1+x2)/((x3-x1)*(x3-x2)))
    let c = (y1*x2*x3/((x1-x2)*(x1-x3))+y2*x1*x3/((x2-x1)*(x2-x3))+y3*x1*x2/((x3-x1)*(x3-x2)))

    return (a, b, c)
}

func calcParabolaYVal(a:Float, b:Float, c:Float, x:Float)->Float{
    return a * x * x + b * x + c
}

func drawLine(x1: Float, y1: Float,x2: Float, y2: Float) {
    println("drawLine \(x1) \(y1) \(x2) \(y2)")
    let positions: [Float32] = [
        x1, y1, 0,
        x2, y2, 0
    ]
    let positionData = NSData(bytes: positions, length: sizeof(Float32)*positions.count)
    let indices: [Int32] = [0, 1]
    let indexData = NSData(bytes: indices, length: sizeof(Int32) * indices.count)

    let source = SCNGeometrySource(data: positionData, semantic: SCNGeometrySourceSemanticVertex, vectorCount: indices.count, floatComponents: true, componentsPerVector: 3, bytesPerComponent: sizeof(Float32), dataOffset: 0, dataStride: sizeof(Float32) * 3)
    let element = SCNGeometryElement(data: indexData, primitiveType: SCNGeometryPrimitiveType.Line, primitiveCount: indices.count, bytesPerIndex: sizeof(Int32))

    let line = SCNGeometry(sources: [source], elements: [element])
    self.rootNode.addChildNode( SCNNode(geometry: line))
}

func renderer(aRenderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: NSTimeInterval) {
    glLineWidth(20)
}

I also need to figure out how to animate an arc from left to right. Can anybody help me? Swift or Object C is great. Any help is appreciated. Thanks!

+3
source share
2 answers

SCNShape . . UIBezierPath. , .

, , , , . - :

let path = UIBezierPath()
path.moveToPoint(CGPointZero)
path.addQuadCurveToPoint(CGPoint(x: 100, y: 0), controlPoint: CGPoint(x: 50, y: 200))

, ( 2D , , 3D SCNShape):

filled parabolafilled parabola in 3D

, , :

let path = UIBezierPath()
path.moveToPoint(CGPointZero)
path.addQuadCurveToPoint(CGPoint(x: 100, y: 0), controlPoint: CGPoint(x: 50, y: 200))
path.addLineToPoint(CGPoint(x: 99, y: 0))
path.addQuadCurveToPoint(CGPoint(x: 1, y: 0), controlPoint: CGPoint(x: 50, y: 198))

open parabolaopen parabola in 3D

.

... Three-Dee!

3D? SCNShape , :

let shape = SCNShape(path: path, extrusionDepth: 10)

:

shape.firstMaterial?.diffuse.contents = SKColor.blueColor()
let shapeNode = SCNNode(geometry: shape)
shapeNode.pivot = SCNMatrix4MakeTranslation(50, 0, 0)
shapeNode.eulerAngles.y = Float(-M_PI_4)
root.addChildNode(shapeNode)

pivot, y = 0 . . , root - , node.

- , x. Shader , per-vertex .

, progress, 0 1, x-:

// declare a variable we can set from SceneKit code
uniform float progress;
// tell SceneKit this shader uses transparency so we get correct draw order
#pragma transparent
// get the position in model space
vec4 mPos = u_inverseModelViewTransform * vec4(_surface.position, 1.0);
// a bit of math to ramp the alpha based on a progress-adjusted position
_surface.transparent.a = clamp(1.0 - ((mPos.x + 50.0) - progress * 200.0) / 50.0, 0.0, 1.0);

Surface, progress:

let modifier = "uniform float progress;\n #pragma transparent\n vec4 mPos = u_inverseModelViewTransform * vec4(_surface.position, 1.0);\n _surface.transparent.a = clamp(1.0 - ((mPos.x + 50.0) - progress * 200.0) / 50.0, 0.0, 1.0);"
shape.shaderModifiers = [ SCNShaderModifierEntryPointSurface: modifier ]
shape.setValue(0.0, forKey: "progress")

SCNTransaction.begin()
SCNTransaction.setAnimationDuration(10)
shape.setValue(1.0, forKey: "progress")
SCNTransaction.commit()

animating parabola

, (iOS). , , :

  • , / . (, SceneKit , .)

  • . , pivot, shapeNode.position - . ( ), y, node. ( ?)

  • - Swift 2, , - Swift-2 - 1.2, , .

  • OS X, - SCNShape NSBezierPath, UIBezierPath . , - .

+19

, , , . , . .

, , , , : y = k * x ^ 2 x = 0 x = T T.

0

Source: https://habr.com/ru/post/1625911/


All Articles