2017-11-02 16 views
0

私は球の周りを動かすときに球の表面にその底を平らに置くように円錐の向きを変えようとしています。SCNNodeを球上のある点から別の点に移動したSCNMatrix4変換を見つけるにはどうすればよいですか?

球は半径4で原点を中心にしています。

変換の四元数を推測しようとしましたが、円錐自体のピボットプロパティを使用する方が簡単です。

私はそれを既知の角度で回転させることで軸上の単純な場所で動作させることができますが、円錐の位置ベクトルから変換を推測する方法はわかりません。私は、球の表面上の点の位置ベクトルと円錐のデフォルトの向きを表すVectorを取って、必要な新しい向きにデフォルトの向きを変換するSCNMatrix4を計算する必要があると思います。次に、それを使ってSCNNodeのピボットを変換することができます。問題の一部は、デフォルトの方向ベクトルが何であるかわからないということです。

これは私が(それが動作しません)これまで持っているものです。

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) 

すべてのヘルプは感謝して

答えて

0

を受けた私は、これは回転軸を見つけるために、クロス製品を使用して動作するようになりました回転角を求めるための点積との積である。これらの機能を使用するには、SCNVectorからGLKVectorに変換する必要があります。コードは次のとおりです。

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) 
関連する問題