2017-07-18 103 views
1

我試圖在下面的代碼中將一個文本字符串(SCNText)放入一個框(SCNBox)中。框的大小看起來是正確的,但文本不在框的正中。任何想法或解決方案?由於SceneKit - SCNText居中不正確

let geoText = SCNText(string: "Hello", extrusionDepth: 1.0) 
geoText.font = UIFont (name: "Arial", size: 8) 
geoText.firstMaterial!.diffuse.contents = UIColor.red 
let textNode = SCNNode(geometry: geoText) 

let (minVec, maxVec) = textNode.boundingBox 
scnScene.rootNode.addChildNode(textNode) 

let w = CGFloat(maxVec.x - minVec.x) 
let h = CGFloat(maxVec.y - minVec.y) 
let d = CGFloat(maxVec.z - minVec.z) 

let geoBox = SCNBox(width: w, height: h, length: d, chamferRadius: 0) 
geoBox.firstMaterial!.diffuse.contents = UIColor.green.withAlphaComponent(0.5) 
scnScene.rootNode.addChildNode(boxNode) 

The text is not the center of the box

編輯:我添加了一個debugOptions showBoundingBoxes字符串(不使用SCNBox節點)的新形象,看看它的邊框

enter image description here

解決方案1:

從vdugnist的回答3210

,我創造的人誰願意操場代碼來測試:

import UIKit 
import SceneKit 
import PlaygroundSupport 

var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 600, height: 600)) 
var scene = SCNScene() 
sceneView.scene = scene 
PlaygroundPage.current.liveView = sceneView 

let geoText = SCNText(string: "Hello", extrusionDepth: 1.0) 
geoText.font = UIFont (name: "Arial", size: 12) 
geoText.firstMaterial!.diffuse.contents = UIColor.red 
let textNode = SCNNode(geometry: geoText) 

let (minVec, maxVec) = textNode.boundingBox 
textNode.position = SCNVector3(x: (minVec.x - maxVec.x)/2, y: minVec.y - maxVec.y, z: 0) 
textNode.pivot = SCNMatrix4MakeTranslation((maxVec.x - minVec.x)/2, 0, 0) 
scene.rootNode.addChildNode(textNode) 

let w = CGFloat(maxVec.x - minVec.x) 
let h = CGFloat(maxVec.y - minVec.y) 
let d = CGFloat(maxVec.z - minVec.z) 

let geoBox = SCNBox(width: w, height: h, length: d, chamferRadius: 0) 
geoBox.firstMaterial!.diffuse.contents = UIColor.green.withAlphaComponent(0.5) 
let boxNode = SCNNode(geometry: geoBox) 
boxNode.position = SCNVector3Make((maxVec.x - minVec.x)/2 + minVec.x, (maxVec.y - minVec.y)/2 + minVec.y, 0); 
textNode.addChildNode(boxNode) 

enter image description here

解決方案2:

我需要移動文本位置零(0 ,0,0),而不是移動文本和周圍的框,因此我繼續更改解決方案1的文本的主軸。現在代碼如下:

import UIKit 
import SceneKit 
import PlaygroundSupport 


var sceneView = SCNView(frame: CGRect(x: 0, y: 0, width: 600, height: 600)) 
var scene = SCNScene() 
sceneView.scene = scene 
PlaygroundPage.current.liveView = sceneView 


let geoText = SCNText(string: "Hello", extrusionDepth: 1.0) 
geoText.font = UIFont (name: "Arial", size: 12) 
geoText.firstMaterial!.diffuse.contents = UIColor.red 
let textNode = SCNNode(geometry: geoText) 

let (minVec, maxVec) = textNode.boundingBox 
textNode.pivot = SCNMatrix4MakeTranslation((maxVec.x - minVec.x)/2 + minVec.x, (maxVec.y - minVec.y)/2 + minVec.y, 0) 
scene.rootNode.addChildNode(textNode) 

let w = CGFloat(maxVec.x - minVec.x) 
let h = CGFloat(maxVec.y - minVec.y) 
let d = CGFloat(maxVec.z - minVec.z) 

let geoBox = SCNBox(width: w, height: h, length: d, chamferRadius: 0) 
geoBox.firstMaterial!.diffuse.contents = UIColor.green.withAlphaComponent(0.6) 
let boxNode = SCNNode(geometry: geoBox) 
scene.rootNode.addChildNode(boxNode) 

回答

1

SCNText與其他幾何圖形的區別在於SCNText原點位於左下角。在其他幾何形狀中,它是底部中心。

要解決的父節點文本位置可以設置其pivotPoint.x至寬度的一半:

SCNVector3 min, max; 
[textNode getBoundingBoxMin:&min max:&max]; 
textNode.pivot = SCNMatrix4MakeTranslation((max.x - min.x)/2, 0, 0); 

要解決的子節點位置,你應該設置自己的地位寬度加分的一半:

SCNVector3 min, max; 
[textNode getBoundingBoxMin:&min max:&max]; 
subnode.position = SCNVector3Make((max.x - min.x)/2 + min.x, (max.y - min.y)/2 + min.y, 0); 
+0

謝謝,但看起來它不是一個解決方案(我已經嘗試過,但它更糟糕 - 也許我不明白你的想法?)。邏輯上,在我的問題圖像中,中心點對於x軸和y軸都不在正確的位置。你的答案只是試圖修復x,顯然這是不夠的。這是最好的,如果你在這裏發佈完整的修復代碼。 – Tony

+1

您是否可以嘗試使用我的第二個解決方案中的座標將盒子節點添加爲文本節點的子節點而不是根節點? 我在代碼中看到的問題是,您將從textNode獲取boundingBox,該文本將在textNode座標系中返回,並在rootNode座標系中使用它們。 – vdugnist

+0

明白了,它現在運作良好! – Tony

0

找到你需要添加邊框的中心(未減去)最小和最大您可以通過2

textNode.position = SCNVector3(x: (minVec.x + maxVec.x)/2, y: minVec.y + maxVec.y, z: 0) 
+0

對不起,但它不是正確的答案。我以點(0,0,0)爲中心,與框類似,不要按照您的建議遠離文本。 – Tony

0

劃分之前,我想你可能會被SCNText起源的異常處理被咬傷。 IIRC Y零點位於字符串的基線,而不是在下行線的底部。

打開showBoundingBoxesdebugOptions看看是否有幫助。

+0

我已打開所有調試選項並已檢查。一切看起來不錯。因此我不知道。也許這是一個API錯誤(因爲代碼非常簡單,邏輯非常清晰)! – Tony

+0

這不太可能是一個API錯誤。但由於它不能按照您的期望工作,因此它可能是一個文檔錯誤。我們可以看到打開邊界框的截圖嗎? –

+0

我無法在此添加圖像(在此評論中)。因此,我編輯了我的問題來添加該圖像。更多信息更好反正 – Tony