如何在潜在场算法中计算两个SKSpriteNode对象之间的距离?

首先声明一下,我完全了解SpriteKit的物理体可以检测碰撞,但这并不是我想要做的。我正在尝试构建一个潜在场AI系统,而计算吸引和排斥向量的一部分需要知道两个对象之间的距离。

我以为计算距离只需使用距离公式就行了,但不知为何我的距离计算结果非常不准确,所以我想咨询一下是否有人能发现我做错了什么。

下面我使用了一个简单的距离公式,点的位置对齐到它们的中心。

func getDistanceBetweenTwoObjects(sourceNode:SKSpriteNode, destinationNode:SKSpriteNode) -> CGFloat{    var centerSourceNode = CGPoint(x: sourceNode.position.x, y: sourceNode.position.y)    centerSourceNode.x += sourceNode.size.width/2    centerSourceNode.y += sourceNode.size.width/2    var centerDestNode = CGPoint(x: destinationNode.position.x, y: destinationNode.position.y)    centerDestNode.x += destinationNode.size.width/2    centerDestNode.y += destinationNode.size.width/2    var distance = sqrt(pow((centerSourceNode.x - centerDestNode.x), 2) + pow((centerSourceNode.y - centerDestNode.y), 2))    return distance}

这是我用来创建吸引向量的函数。

func getAttractionVector(node:SKSpriteNode, destinationNode:SKSpriteNode, spread:CGFloat, strength:CGFloat) -> (xSpeed: CGFloat, ySpeed: CGFloat){    var sourceNodeRadius = sqrt(pow(node.size.width/2,2))    var destNodeRadius = sqrt(pow(destinationNode.size.width/2,2))    var radius = sourceNodeRadius + destNodeRadius    var distance = getDistanceBetweenTwoObjects(node, destinationNode: destinationNode)    if distance < radius{        return (0,0)    }    var angle = atan((destinationNode.position.y - node.position.y)/(destinationNode.position.x - node.position.x))    var xSpeed:CGFloat = 0    var ySpeed:CGFloat = 0    if radius <= distance && distance <= spread + radius{        xSpeed = strength * (distance - radius) * cos(angle)        ySpeed = strength * (distance - radius) * sin(angle)    }else if distance > spread + radius{        xSpeed = strength * spread * cos(angle)        ySpeed = strength * spread * sin(angle)    }    return (xSpeed, ySpeed)}

我使用类似的数学方法来计算排斥向量:

    func getRepelVector(node:SKSpriteNode, destinationNode:SKSpriteNode, spread:CGFloat, strength:CGFloat) -> (xSpeed: CGFloat, ySpeed: CGFloat){    var sourceNodeRadius = sqrt(pow(node.size.width/2,2))    var destNodeRadius = sqrt(pow(destinationNode.size.width/2,2))    var radius = sourceNodeRadius + destNodeRadius    var distance = getDistanceBetweenTwoObjects(node, destinationNode: destinationNode)    if distance > spread + radius{        return (0,0)    }    var angle = atan((destinationNode.position.y - node.position.y)/(destinationNode.position.x - node.position.x))    var xSpeed:CGFloat = 0    var ySpeed:CGFloat = 0    println("\(distance) : \(radius)")    if radius <= distance && distance <= spread + radius{        xSpeed = strength * (spread + radius - distance) * cos(angle)        ySpeed = strength * (spread + radius - distance) * sin(angle)    }else if distance < radius{        xSpeed = getSign(cos(angle)) * CGFloat.max        ySpeed = getSign(sin(angle)) * CGFloat.max        println("HERE")    }    return (xSpeed, ySpeed)}

不幸的是,距离公式显然对我不起作用,我多次发现节点在接触时没有被检测到,或者在未接触时被误认为是接触的。是否有人能看出我哪里做错了,或者建议一个更简单的方法来准确计算两个SpriteNodes之间的距离?希望问题很简单。谢谢。

下图显示了我的AINode解决迷宫(橙色),一个需要避开的障碍物(蓝色)和我的目标(绿色)。

在这个例子中,AINode的宽度为20。障碍物的宽度为50。

在调试器暂停在AINode非法穿越障碍物的无效状态下,使用上述公式计算中心点之间的距离读数为“28.28”。实际距离是7。 enter image description here

更新

我发现我的吸引和排斥向量存在一个重大错误,这加剧了问题。我的距离公式有点偏差,但由于我计算角度的方式错误而被放大了。角度需要使用atan2而不是atan来计算。原因是如果不使用atan2,返回的角度将位于错误的象限,这扭曲了排斥向量的方向并导致了重大错误。


回答:

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注