我有问题。我创建了一个看起来像这样的列表:
public class TriangleRegistryList
{
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 int ShapeNum { get; set; }
public IEnumerable<(float x, float y)> GetPoints()
{
yield return (x1, y1);
yield return (x2, y2);
yield return (x3, y3);
}
public bool IsAdjacentTo(TriangleRegistryList other)
{
return GetPoints().Intersect(other.GetPoints()).Count() >= 2;
}
}
现在我也创建了此类:
public static class EnumerableExtensions
{
public static IEnumerable<IEnumerable<T>>
GetKCombs<T>(this IEnumerable<T> list, int length)
{
if (length == 1) return list.Select(t => new T[] { t });
return GetKCombs(list, length - 1)
.SelectMany(t => list.Where(o => !o.Equals(t.Last())),
(t1, t2) => t1.Concat(new T[] { t2 }));
}
}
这将检查我的三角形是否彼此共享边。为此,我必须致电以下行:
var sharedEdges =
triangles.GetKCombs(2)
.Where(t =>
t.First().IsAdjacentTo(t.Skip(1).Take(1).Single())
&& t.First().ShapeNum == 1
);
现在我想知道如何获取三角形所连接的三角形的ShapeNum。因此,例如,如果我有一个带有ShapeNum的三角形,并且看到它与另一个三角形具有共享边,那么我想知道那个三角形的ShapeNum是什么。
详细信息:
当列表中有几个三角形时,我将检查下一个三角形,我想知道哪个已连接三角形的ShapeNum最低。因此,例如以下图片:
然后我想要一个返回我1的结果,因为那是与绿色三角形相连的最低三角形。下一步将是获取另一个数字,因此在我的示例中为2。然后将每个ShapeNum = 2的Triangle设置为1。因此,图片如下所示:
更新:
我现在创建了这个函数:
public static bool ValidLayout()
{
bool TriangleFound = false;
bool IsValid;
int SelectedTriangles = TriangleRegistry.Count(tr => tr.Value.Selected.Equals(true));
int LowestShapeNum = 0;
triangles = new List<TriangleRegistryList>();
/*
foreach (KeyValuePair<string, TriangleRegistryObject> row in TriangleRegistry.Where(n => n.Value.Selected == true).ToList())
{
triangles.Add(new TriangleRegistryList
{
x1 = row.Value.x1,
y1 = row.Value.y1,
x2 = row.Value.x2,
y2 = row.Value.y2,
x3 = row.Value.x3,
y3 = row.Value.y3,
ShapeNum = 0
});
}
*/
triangles.Add(new TriangleRegistryList
{
x1 = (float)405,
y1 = (float)701.4806,
x2 = (float)675,
y2 = (float)701.4806,
x3 = (float)540,
y3 = (float)935.3074
});
triangles.Add(new TriangleRegistryList
{
x1 = (float)135,
y1 = (float)701.4806,
x2 = (float)405,
y2 = (float)701.4806,
x3 = (float)270,
y3 = (float)935.3074
});
triangles.Add(new TriangleRegistryList
{
x1 = (float)270,
y1 = (float)935.3074,
x2 = (float)540,
y2 = (float)935.3074,
x3 = (float)405,
y3 = (float)701.4806
});
int maxShapeNum = triangles.Max(x => x.ShapeNum);
foreach (TriangleRegistryList triangle in triangles)
{
if(maxShapeNum > 0)
{
int i = 1;
while(i <= maxShapeNum)
{
//Check if the current triangle with (ShapeNumber = i) is connected to another triangle from the list
var sharedEdges = triangles.GetKCombs(2).Where(t => t.First().IsAdjacentTo(t.Skip(1).Take(1).Single()) && t.Skip(1).Single().ShapeNum == i);
int sharedEdgesCount = sharedEdges.Count();
if (sharedEdgesCount > 0)
{
List<int> ConnectedShapeNumList = triangle.AdjacentShapeNumbers;
if (ConnectedShapeNumList != null)
{
List<int> RemovedDoublesList = ConnectedShapeNumList.Distinct().ToList();
RemovedDoublesList.Sort();
int ListLength = (from x in RemovedDoublesList select x).Distinct().Count();
if(ListLength != 0)
{
LowestShapeNum = RemovedDoublesList.First();
int HighestShapeNum = RemovedDoublesList.Last();
if (sharedEdgesCount > 1)
{
if (LowestShapeNum != HighestShapeNum)
{
foreach (int x in RemovedDoublesList)
{
if (x != LowestShapeNum)
{
foreach (TriangleRegistryList OldTriangleShapeNum in triangles)
{
if (OldTriangleShapeNum.ShapeNum == x)
{
OldTriangleShapeNum.ShapeNum = LowestShapeNum;
}
}
}
}
}
else
{
triangle.ShapeNum = RemovedDoublesList.First();
}
}
else
{
triangle.ShapeNum = RemovedDoublesList.First();
}
}
else
{
triangle.ShapeNum = maxShapeNum + 1;
}
}
}
else
{
triangle.ShapeNum = maxShapeNum + 1;
}
TriangleFound = true;
i += 1;
}
}
if(TriangleFound == false)
{
triangle.ShapeNum = maxShapeNum + 1;
}
maxShapeNum = triangles.Max(x => x.ShapeNum);
}
if (maxShapeNum == 1)
{
IsValid = true;
}
else
{
IsValid = false;
}
return IsValid;
}
有时候代码确实可以工作,但是有时当所有三角形连接在一起时,它仍然表示检测到多个形状。我已经在上面的代码中手动添加了三角形坐标,因此您可以自己尝试。这是无效的地层的三角形坐标(实际上应该有效):
TriangleRegistryList Triangle_1 = new TriangleRegistryList
{
x1=405, y1=701.4806, x2=675, y2=701.4806, x3=540, y3=935.3074
};
TriangleRegistryList Triangle_2 = new TriangleRegistryList
{
x1=135, y1=701.4806, x2=405, y2=701.4806, x3=270, y3=935.3074
};
TriangleRegistryList Triangle_3 = new TriangleRegistryList
{
x1=270, y1=935.3074, x2=540, y2=935.3074, x3=405, y3=701.4806
};
答案 0 :(得分:1)
您应该能够通过将整数属性“ AdjacentShapeNum”添加到“ TriangleRegistryList”中,并在找到与另一个三角形的共享边的情况下,在“ IsAdjacentTo”方法中对其进行设置。
public int AdjacentShapeNum { get; set; }
public bool IsAdjacentTo(TriangleRegistryList other)
{
var isAdjacentTo =
GetPoints().Intersect(other.GetPoints()).ToList().Count() >= 2;
if(isAdjacentTo){
this.AdjacentShapeNum = other.ShapeNum;
}
return isAdjacentTo;
}
获取与当前三角形相邻的多个三角形的“ ShapeNum”的代码:
public TriangleRegistryList()
{
this.AdjacentShapeNumbers = new List<int>();
}
public List<int> AdjacentShapeNumbers {get;set;}
public bool IsAdjacentTo(TriangleRegistryList other)
{
var isAdjacentTo =
GetPoints().Intersect(other.GetPoints()).ToList().Count() >= 2;
if(isAdjacentTo){
this.AdjacentShapeNumbers.Add(other.ShapeNum);
}
return isAdjacentTo;
}