我有问题。我想相互比较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个六角形。
我在做什么错了?
答案 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-没问题。如果您有三点话,请说:
Equals(x, z)
和a
接近,b
和b
接近,但是{{1} }和c
没有关闭寻求邻近与请求平等不同-您想要的是前者。
我知道这个答案并没有告诉您应该怎么做-而是向您显示出您要去哪里。我认为您需要彻底改变自己的方法。对我来说,尚不十分清楚您要用哪种方法实现,但是您可能要考虑寻找点之间的距离,而不是将它们视为相等。