A. Vreeswijk
A. Vreeswijk

Reputation: 954

Count connected lines

I have a problem. I created a TriangleGrid using SkiaSharp. While I was drawing the grid I saved each triangle info in a Dictionary. The Dictionary looks like this:

public class TriangleRegistryObject
{
    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 bool Selected { get; set; }
    public bool Visible { get; set; }
}

Now when I select a Triangle I set the boolean Selected to true. At the end I want to check if the Triangles I have selected are connected with eachother. I thought I could count the connected lines. Here is an example image: enter image description here

Now I want to count the purple lines where Selected=true. I have every coordinate (x1, y1) (x2, y2) and (x3, y3).

UPDATE: Here is the code I use that return 0 for me!

public static bool ValidLayout()
{
    bool IsValid;
    int sharedEdges;
    int SelectedTriangles = TriangleRegistry.Count(tr => tr.Value.Selected.Equals(true));
    var 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
        });
    }

    sharedEdges = triangles.GetKCombs(2).Where(t => t.First().IsAdjacentTo(t.Skip(1).Take(1).Single())).Count();

    if (sharedEdges >= (SelectedTriangles - 1))
    {
        IsValid = true;
    }
    else
    {
        IsValid = false;
    }

    return IsValid;
}

But I have no idea how I can compare the coordinates with each other, to count the connected lines!

Can someone help me?

Upvotes: 2

Views: 126

Answers (1)

Bradley Uffner
Bradley Uffner

Reputation: 16991

Here is a very simple solution. It definitely isn't the most efficient, but it gets the job done.

I've added a method to your triangle class that returns true if it shares at least 2 vertices with another triangle.

I've also used a method of finding the distinct permutations that is slightly modified from the one discussed here.

public class Program
{
    public static void Main()
    {
        var triangles = new List<TriangleRegistryObject>{
            new TriangleRegistryObject{x1=10,y1=10, x2=12,y2=10, x3=1,y3=11},
            new TriangleRegistryObject{x1=9,y1=11, x2=11,y2=11, x3=10,y3=10},
            new TriangleRegistryObject{x1=9,y1=11, x2=11,y2=11, x3=10,y3=12},
            new TriangleRegistryObject{x1=34,y1=14, x2=15,y2=11, x3=10,y3=12},
        };

        var sharedEdges = triangles.GetPairs().Where(t => t.first.IsAdjacentTo(t.second)).Count();
        Console.WriteLine($"Number shared edges: {sharedEdges}");
    }
}

public class TriangleRegistryObject
{
    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 bool Selected { get; set; }
    public bool Visible { get; set; }

    public IEnumerable<(float x, float y)> GetPoints()
    {
        yield return (x1, y1);
        yield return (x2, y2);
        yield return (x3, y3);
    }

    public bool IsAdjacentTo(TriangleRegistryObject other)
    {
        return this.GetPoints().Intersect(other.GetPoints()).Count() >= 2;
    }
}

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

Upvotes: 2

Related Questions