【问题标题】:Pulling force between two physics bodies connected by a joint由关节连接的两个物理体之间的拉力
【发布时间】:2020-04-16 16:15:38
【问题描述】:

我想做的事:

我创建了两个SCNNodes 和对应的SCNPhysicsBodys(都是动态的和受重力影响的),我想使用SCNPhysicsHingeJoint 连接它们。只是为了测试一下node1 有一个额外的关节,以便固定在场景中并且不会因重力而掉落。这些节点通过joint 相互连接。所以当我开始场景时,node1 只是固定在场景中,node2 是向下悬挂的。现在我想确定拉动关节的力应该等于-9.8(假设没有摆动)因为gravitational acceleration is equals -9.8gravity属性的默认值)和默认质量等于1其中拉关节的力应为-9.8。不过,我不想计算拉力,因为我的场景要变得相当复杂。 因此我想知道是否有一种属性或方法可以计算两个节点之间的拉力以及通过关节连接的物理体?

let node1 = SCNNode(geometry: SCNCylinder(radius: 0.125, height: 2))
node1.position.x = -1.625
node1.rotation = SCNVector4(1, 0, 0, Float.pi/2)
node1.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry: node1.geometry!, options: nil))
node1.physicsBody!.isAffectedByGravity = true
node1.physicsBody!.categoryBitMask = 1
node1.physicsBody!.contactTestBitMask = 1
node1.physicsBody!.collisionBitMask = 1
rootNode.addChildNode(node1)

let node2 = SCNNode(geometry: SCNBox(width: 3, height: 0.25, length: 2, chamferRadius: 0))
node2.physicsBody = SCNPhysicsBody(type: .dynamic, shape: SCNPhysicsShape(geometry: node2.geometry!, options: nil))
node2.physicsBody!.isAffectedByGravity = true
node2.physicsBody!.categoryBitMask = 1
node2.physicsBody!.contactTestBitMask = 1
node2.physicsBody!.collisionBitMask = 1
rootNode.addChildNode(node2)

let irrelevantJoint = SCNPhysicsHingeJoint(body: node1.physicsBody!, axis: SCNVector3(0, 1, 0), anchor: SCNVector3(0, 0, -0.125))
physicsWorld.addBehavior(irrelevantJoint)

let joint = SCNPhysicsHingeJoint(bodyA: node1.physicsBody!, axisA: SCNVector3(0, 1, 0), anchorA: SCNVector3(0, 0, 0.125),
                                 bodyB: node2.physicsBody!, axisB: SCNVector3(0, 0, 1), anchorB: SCNVector3(-1.5, 0, 0))
physicsWorld.addBehavior(joint)

我尝试了什么:

我希望我可以使用SCNPhysicsContactDelegatephysicsWorld(_:didEnd:) 来获得joint 的力量(或冲动)。每当该方法被调用时,就会创建一个 SCNPhysicsContact,它允许您访问它的 collisionImpulse 属性,所以我希望有一个负面的冲动,但事实并非如此。我刚刚得到 0 和 collisionImpulse关于如何获得通过关节连接的两个物理体之间的拉力的任何想法?

【问题讨论】:

  • 您确定选择了正确的仪器吗? *SCNPhysicsHingeJoint* 一种物理行为,它连接两个物体并允许它们在一个轴上相互绕轴转动。 因此这两个物体之间不可能发生碰撞,不是吗?
  • 是的,我认为是。我希望两个节点(及其物理体)相互连接,node2 应该围绕node1 摆动。 另外我想确定拉那个枢轴的力或node1

标签: swift scenekit game-physics


【解决方案1】:

游戏物理模拟不需要简单关节中的力计算。这些是几何约束,收敛是通过求解器迭代实现的。力计算是一项额外的费用,它会花费计算时间,并且在综合求解器中,默认情况下会显式启用和禁用。并不是所有的求解器都有这个,看着SCNPhysicsWorld我没有看到任何迹象,所以我很确定它没有实现。

从积极的方面来说,我相信施加到场景中每个身体的力的计算非常简单。您只需在每帧更新身体的当前帧和前一帧速度,并将加速度计算为它们的差除以时间戳。将它乘以体重,这会给你力量。同样的,你可以根据物体的惯性计算出角速度和扭矩。

如果您确实需要关节中的力和扭矩,这并不简单,所以我唯一能建议的就是描述您打算如何使用它,看看是否有替代解决方案来实现这一最终目标.

【讨论】:

  • 问题是节点没有移动,我只想计算关节上的应力...(因此速度没有变化)
  • 恐怕没有变通办法,您必须自己计算静态反作用力(engineer4free.com/4/how-to-solve-3d-statics-problemsengineer4free.com/statics.html)或使用求解器为您进行此计算跨度>
  • 你将如何计算例如一座不动的桥上的力......当 f.e.一辆汽车驶过它
  • 简短回答 - 如我发布的视频中所述。长答案,取决于精度。在最简化的情况下(零车辆加速度和反作用力是基于单点接触 F=Mg 计算的,而不是 4 个车轮和桥梁假定为 2 个铰接点,具有反作用力 F1 和 F2),您有 2 个方程 F1 +F2=F 和 F1*L1=F2*L2 其中 L1 和 L2 是当前帧上从桥端到车辆的距离。如果一座桥不是平的,你将不得不在 2D 中做矢量数学等等。
【解决方案2】:

正如 isp-zax 所描述的,您可以使用由经过的时间决定的 delta v,从而确定加速度。

var node1: SCNNode!
var timestamp: TimeInterval = 0
var lastVelocity: SCNVector3 = SCNVector3()
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    let dt = time - timestamp
    timestamp = time

    let velocity = node1.physicsBody!.velocity
    let dv = velocity.y - lastVelocity.y
    let a = Double(dv) / dt
    lastVelocity = velocity

    print("vertical acceleration: \(a) and vertical force: \(node1.physicsBody!.mass * a)")
}

您必须将SCNViewdelegate 属性分配给实现上述方法的处理程序。此外,您需要处理程序符合SCNSceneRendererDelegate 协议。上面的代码只是计算垂直加速度,但是你可以在 y 和 z 方向上做同样的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多