比较两个 CGPoints 是否相等:对于输出相同点的两个对象返回不相等?

Cra*_*lot 4 core-graphics ios swift

根据这个问题,使用 == 和 != 应该让您检查两个CGPoint对象之间的相等性。

但是,下面的代码无法将两个CGPoint对象视为相等,即使它们输出相同的值。

检查CGPoint对象之间相等性的正确方法是什么?

代码:

    let boardTilePos = boardLayer.convert(boardTile.position, from: boardTile.parent!)
    let shapeTilePos = boardLayer.convert(tile.position, from: tile.parent!)   
    print("board tile pos: \(boardTilePos). active tile pos: \(shapeTilePos). true/false: \(shapeTilePos == boardTilePos)")
Run Code Online (Sandbox Code Playgroud)

输出:

board tile pos: (175.0, 70.0). active tile pos: (175.0, 70.0). true/false: false
Run Code Online (Sandbox Code Playgroud)

Kni*_*gon 6

不幸的是,您在控制台中看到的并不是您的真正价值。

import UIKit

var x = CGPoint(x:175.0,y:70.0)
var y = CGPoint(x:175.0,y:70.00000000000001)

print("\(x.equalTo(y)), \(x == y),\(x),\(y)")
Run Code Online (Sandbox Code Playgroud)

问题是,控制台只允许 10 -16但实际上你CGFloat可以比这更低,因为在 64 位架构上,CGFloatDouble.

这意味着如果您想获得将出现在控制台上的相等,您必须将您的CGPoint值转换为 a Float,因此您需要执行以下操作:

if Float(boxA.x) == Float(boxB.x) && Float(boxA.y) == Float(boxB.y)
{
  //We have equality
}
Run Code Online (Sandbox Code Playgroud)

现在我喜欢更进一步。

在大多数情况下,我们使用 CGPoint 来确定场景中的点。我们很少想处理 1/2 点,它们让我们的生活变得混乱。

所以,而不是Float,我喜欢投射到Int. 这将保证两个点CGPoint在场景空间中是否位于同一点上

if Int(boxA.x) == Int(boxB.x) && Int(boxA.y) == Int(boxB.y)
{
  //We have equality
}
Run Code Online (Sandbox Code Playgroud)


JAL*_*JAL 6

我提供了一个替代答案,因为我不同意 Knight0fDragon 的实现。这仅适用于您要处理某个点的派系。如果您只关心整数点,请参阅 Knight0fDragon 的回答。

您并不总是能够将点记录到控制台,或者查看您是否试图比较浮点数学的牺牲品,例如比较 (175.0, 70.0) 和 (175.0, 70.00001)(两者都是在控制台中记录为 (175.0, 70.0))。是的,截断为 Int 是一种很好的方式来理解为什么两个点在控制台上打印出来的结果并不相等。但这并不是用来比较每一点的一个包罗万象的解决方案。根据您需要的精度级别,您希望获取每个点的 x 和 y 差值的绝对值,并查看它是否在您指定的可接受的增量范围内。

var boxA = CGPoint(x:175.0, y:70.0)
var boxB = CGPoint(x:175.0, y:70.00000000000001)

let delta: CGFloat = 0.01

if (fabs(boxA.x - boxB.x) < delta) &&
   (fabs(boxA.y - boxB.y) < delta) {
    // equal enough for our needs
}
Run Code Online (Sandbox Code Playgroud)

“检查CGPoint对象之间相等性的正确方法是什么?”这个问题的答案。实际上取决于您比较浮点数的方式。