问题:我在3D空间中有两点A& B定义轴。 A& B不断变化。我也有一个C点随意移动。我需要在Swift func isInsideCapsule() -> Bool
中编写一个函数,它返回点C是否位于围绕轴A-B形成的虚拟3D封壳内。该功能采用三点 A , B , C &胶囊半径 r 作为输入&返回Bool,true或false。任何人都可以解决这个问题吗?即使只是指向正确方向的数学计算也会有所帮助。我可以解决Swift ..
答案 0 :(得分:0)
如果从点C到线AB的距离<半径然后点C在胶囊内。
所以你真正需要的是一个检查从线段到点的距离的函数。在下面的SO问题中,您可以轻松地将不同语言的许多有效答案转换为Swift。 Shortest distance between a point and a line segment使用一个用于有限线。
答案 1 :(得分:0)
对于那些感兴趣的人,这里是我如何做到的(带有限制音量风格的选项),在Swift 4中;
enum LineBoundingPrimitive: String {
case infiniteCylinder
case cylinder
case capsule
}
func cameraIsOutsideLineBoundingPrimitive(_ boundingPrimitive: LineBoundingPrimitive, A: SCNVector3!, B: SCNVector3!, radius: Float!) -> Bool! {
guard let C = viewController?.ARView.pointOfView?.worldPosition else { return true }
// First find the relative positions
let BA = SCNVector3Make(B.x-A.x, B.y-A.y, B.z-A.z)
let CA = SCNVector3Make(C.x-C.x, C.y-A.y, C.z-A.z)
let lengthBA = SCNVector3Distance(vectorStart: A, vectorEnd: B)
let lengthCA = SCNVector3Distance(vectorStart: A, vectorEnd: C)
// Find position of closest point along the length of the line, normalized to it's length
let k = SCNVector3DotProduct(left: BA, right: CA)/(lengthBA*lengthBA)
switch boundingPrimitive {
case .infiniteCylinder:
break
case .cylinder:
if k < 0 || k > 1 { return true }
case .capsule:
if k < 0 {
//Is C within sphere around A
return lengthPA > radius ? true : false
} else if k > 1 {
let lengthPB = SCNVector3Distance(vectorStart: P, vectorEnd: B)
//Is C within sphere around B
return lengthPB > radius ? true : false
}
}
let rightAngleDistanceFromLine = lengthPA-lengthBA*k
// Are we inside the capsule?
return radius < distanceFromTether ? true : false
}
func SCNVector3Distance(vectorStart: SCNVector3, vectorEnd: SCNVector3) -> Float {
return SCNVector3Length(vectorEnd - vectorStart)
}
func SCNVector3DotProduct(left: SCNVector3, right: SCNVector3) -> Float {
return left.x * right.x + left.y * right.y + left.z * right.z
}