2017-11-02 2 views
0

Ich versuche einen Kegel so umzuorientieren, dass er mit seiner Basis flach auf der Oberfläche einer Kugel sitzt, während ich ihn um die Kugel bewege.Wie finde ich die SCNMatrix4-Umwandlung, die einen SCNNode von einem Punkt auf einer Kugel in einen anderen verschoben hat?

Die Kugel ist Radius 4 und zentriert am Ursprung.

Ich habe versucht, die Quaternion für die Transformation abzuleiten, aber es scheint einfacher zu sein, die Pivot-Eigenschaft des Kegels selbst zu verwenden.

Ich kann es an einfachen Stellen auf den Achsen arbeiten, indem ich es durch bekannte Winkel rotiere, aber ich kann nicht herausfinden, wie man die Transformation vom Ortsvektor des Kegels ableitet. Ich denke, ich muss den Vektor nehmen, der die Standardausrichtung des Kegels und den Ortsvektor des Punkts auf der Oberfläche der Kugel darstellt, und die SCNMatrix4 ausarbeiten, die die Standardausrichtung in die neue, die ich brauche, umwandelt. Dann kann ich es verwenden, um den Drehpunkt des SCNNode zu transformieren. Ein Teil des Problems ist, dass ich nicht weiß, was die Standardausrichtung Vektor ist.

Dies ist, was ich bisher (es funktioniert nicht):

let distanceFromCentre = Float(4.0) 
let newConeNode = SCNNode(geometry: SCNCone(topRadius: 0, bottomRadius: 0.5, height: 1.0)) 
let radialLocationVector = SCNVector3Make(0.0, 1.0, 1.0) 
let radialLocationVectorMagnitude = pow((pow(radialLocationVector.x,2) + pow(radialLocationVector.y,2) + pow(radialLocationVector.z,2)),0.5) 
let radialLocationUnitVector = SCNVector3Make(radialLocationVector.x/radialLocationVectorMagnitude, radialLocationVector.y/radialLocationVectorMagnitude, radialLocationVector.z/radialLocationVectorMagnitude) 
let surfaceLocationVector = SCNVector3Make(radialLocationUnitVector.x*distanceFromCentre, radialLocationUnitVector.y*distanceFromCentre, radialLocationUnitVector.z*distanceFromCentre) 
newConeNode.position = surfaceLocationVector 

let nodePivotRotationMatrix = SCNMatrix4MakeRotation(0,radialLocationUnitVector.x, radialLocationUnitVector.y, radialLocationUnitVector.z) //This doesn't work 

let nodePivotTranslationMatrix = SCNMatrix4MakeTranslation(0, -0.5, 0) 
newConeNode.pivot = SCNMatrix4Mult(nodePivotRotationMatrix, nodePivotTranslationMatrix) 

newConeNode.name = "MyCone" 
newConeNode.geometry?.firstMaterial?.diffuse.contents = UIColor(red: 0.2, green: 0, blue: 0.8, alpha: 1.0) 
scnView.scene?.rootNode.addChildNode(newConeNode) 

Jede Hilfe dieses dankbar

erhielt

Antwort

0

Ich habe mithilfe des Kreuzprodukt zu arbeiten, um die Drehachse finden und das Skalarprodukt, um den Rotationswinkel zu finden. Sie müssen von SCNVector in GLKVector konvertieren, um diese Funktionen zu verwenden. Der Code ist unten:

let distanceFromCentre = globeNode!.geometry!.boundingSphere.radius 
let newConeNode = SCNNode(geometry: SCNCone(topRadius: 0, bottomRadius: 0.5, height: 1.0)) 
let northPoleLocationVector = SCNVector3Make(0.0, distanceFromCentre, 0) 
newConeNode.position = northPoleLocationVector 

let newLocationDirectionVector = SCNVector3Make(1.0, 2.0, 3.0) 
let magnitudeLocation = Float(pow((pow(newLocationDirectionVector.x,2) + pow(newLocationDirectionVector.y,2) + pow(newLocationDirectionVector.z,2)),0.5)) 
let newLocationUnitVector = SCNVector3Make(newLocationDirectionVector.x/magnitudeLocation, newLocationDirectionVector.y/magnitudeLocation, newLocationDirectionVector.z/magnitudeLocation) 
let newLocationOnSurface = SCNVector3Make(newLocationUnitVector.x*distanceFromCentre, newLocationUnitVector.y*distanceFromCentre, newLocationUnitVector.z*distanceFromCentre) 
let locationTranslationVector = SCNVector3Make(northPoleLocationVector.x-newLocationOnSurface.x, northPoleLocationVector.y-newLocationOnSurface.y, northPoleLocationVector.z-newLocationOnSurface.z) //Not sure why this works - the vector from A to B should be b-a not a-b 
let surfaceTranslationMatrix = SCNMatrix4MakeTranslation(locationTranslationVector.x, locationTranslationVector.y, locationTranslationVector.z) 

let northPoleLocationVectorGLK = GLKVector3Make(northPoleLocationVector.x, northPoleLocationVector.y, northPoleLocationVector.z) 
let magnitudeSLV = GLKVector3Length(northPoleLocationVectorGLK) 
let newLocationOnSurfaceVectorGLK = GLKVector3Make(newLocationOnSurface.x, newLocationOnSurface.y, newLocationOnSurface.z) 
let magnitudeNLV = GLKVector3Length(newLocationOnSurfaceVectorGLK) 
let normalToTransformGLK = GLKVector3CrossProduct(northPoleLocationVectorGLK, newLocationOnSurfaceVectorGLK) 
let angleOfRotation = acos(GLKVector3DotProduct(northPoleLocationVectorGLK, newLocationOnSurfaceVectorGLK)/(magnitudeNLV*magnitudeSLV)) 
let coneRotationMatrix = SCNMatrix4MakeRotation(-angleOfRotation, normalToTransformGLK.x, normalToTransformGLK.y, normalToTransformGLK.z) 

let combinedTransformMatrix = SCNMatrix4Mult(surfaceTranslationMatrix, coneRotationMatrix) 
newConeNode.pivot = combinedTransformMatrix 

newConeNode.name = "MyCone" 
newConeNode.geometry?.firstMaterial?.diffuse.contents = UIColor(red: 0.2, green: 0, blue: 0.8, alpha: 1.0) 
scnView.scene?.rootNode.addChildNode(newConeNode) 
Verwandte Themen