从具有共享边的列表中获取行的特定值

时间:2019-05-20 06:08:34

标签: c#

我有问题。我创建了一个看起来像这样的列表:

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最低。因此,例如以下图片: enter image description here

然后我想要一个返回我1的结果,因为那是与绿色三角形相连的最低三角形。下一步将是获取另一个数字,因此在我的示例中为2。然后将每个ShapeNum = 2的Triangle设置为1。因此,图片如下所示: enter image description here



更新: 我现在创建了这个函数:

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
};

1 个答案:

答案 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;
        }