比较不完全相同的坐标

时间:2019-05-21 13:25:49

标签: c#

我有问题。我想相互比较2个坐标,但是坐标不必完全相同。允许的最大差异为0,1。所以我创建了这段代码:

public class HexagonRegistryList
{
    public int HexagonNum { get; set; }
    public float x1 { get; set; }
    public float y1 { get; set; }
    public float x2 { get; set; }
    public float y2 { get; set; }
    public float x3 { get; set; }
    public float y3 { get; set; }
    public float x4 { get; set; }
    public float y4 { get; set; }
    public float x5 { get; set; }
    public float y5 { get; set; }
    public float x6 { get; set; }
    public float y6 { get; set; }
    public int ShapeNum { get; set; }

    public HexagonRegistryList()
    {
        this.AdjacentShapeNumbers = new List<int>();
    }

    public List<int> AdjacentShapeNumbers { get; set; }

    public IEnumerable<(float x, float y)> GetPoints()
    {
        yield return (x1, y1);
        yield return (x2, y2);
        yield return (x3, y3);
        yield return (x4, y4);
        yield return (x5, y5);
        yield return (x6, y6);
    }

    public struct PointComparer : IEqualityComparer<(float x, float y)>
    {
        public bool Equals((float x, float y) p1, (float x, float y) p2)
        {
            return Math.Abs(p1.x - p2.x) < 0.1f && Math.Abs(p1.y - p2.y) < 0.1f;
        }

        public int GetHashCode((float x, float y) obj)
        {
            return obj.GetHashCode();
        }
    }

    public bool IsAdjacentTo(HexagonRegistryList other)
    {
        //var isAdjacentTo = GetPoints().Intersect(other.GetPoints()).Count() >= 2;
        var isAdjacentTo = GetPoints().Intersect(other.GetPoints(), new PointComparer()).Count() >= 2;
        if (isAdjacentTo)
        {
            if (other.ShapeNum != 0)
            {
                AdjacentShapeNumbers.Add(other.ShapeNum);
            }
        }
        return isAdjacentTo;
    }
}

现在到达该行时:var isAdjacentTo = GetPoints().Intersect(other.GetPoints(), new PointComparer()).Count() >= 2;它返回false,这应该是正确的。这是坐标:

x1 = 607.5
y1 = 935.3075

x2 = 607.5
y2 = 935.3074

如您所见,y坐标相差0.0001,但这对我的代码来说应该不是问题。但是出于某种原因,它说这些坐标不匹配!

我正在比较六角形的边,所以这是我要做的主要电话:

var sharedEdges = hexagons.GetPairs().Where(t => hexagon.IsAdjacentTo(hexagons[i]));

我也正在使用此类进行比较:

public static class EnumerableExtensions
{
    public static IEnumerable<(T first, T second)> GetPairs<T>(this IEnumerable<T> list)
    {
        return list.SelectMany((value, index) => list.Skip(index + 1),
                                (first, second) => (first, second));
    }
}

六角形是一个列表,而六角形只是列表中的1个六角形。

我在做什么错了?

1 个答案:

答案 0 :(得分:6)

我怀疑问题在于use Keygen; $id = Keygen::numeric(10)->generate(); 正在有效地建立一个哈希集以进行相等性比较。您的两个“几乎相等”的坐标不会具有相同的哈希码,因此甚至不会调用Intersect。您可以通过始终返回0来实现Equals,但是从根本上来说,您仍然遇到很大的问题:相等比较器无法按预期实现IEqualityComparer<T>。平等比较器应遵守GetHashCode的这些规则:

  • 反身:Equals应该返回true-很好
  • 对称:Equals(x, x)应该返回Equals(x, y)-也可以
  • 可传递性:如果Equals(y, x)Equals(x, y)返回true,那么Equals(y, z)也应返回true-没问题。

如果您有三点话,请说:

  • a =(0,0)
  • b =(0.09,0)
  • c =(0.18,0),那么您说Equals(x, z)a接近,bb接近,但是{{1} }和c没有关闭

寻求邻近与请求平等不同-您想要的是前者。

我知道这个答案并没有告诉您应该怎么做-而是向您显示出您要去哪里。我认为您需要彻底改变自己的方法。对我来说,尚不十分清楚您要用哪种方法实现,但是您可能要考虑寻找点之间的距离,而不是将它们视为相等。