private int GetIntersectionsBetweenTwoPaths(ConnectionPath pathA, ConnectionPath pathB)
        {
            int intersectionsTotal = 0;

            var lineA = GetPolylineFromPath(pathA);

            Segment[] segmentsA = new Segment[]
            {
                new Segment((int)lineA.Points[0].X, (int)lineA.Points[0].Y, (int)lineA.Points[1].X, (int)lineA.Points[1].Y),
                new Segment((int)lineA.Points[1].X, (int)lineA.Points[1].Y, (int)lineA.Points[2].X, (int)lineA.Points[2].Y),
                new Segment((int)lineA.Points[2].X, (int)lineA.Points[2].Y, (int)lineA.Points[3].X, (int)lineA.Points[3].Y)
            };

            var lineB = GetPolylineFromPath(pathB);

            Segment[] segmentsB = new Segment[]
            {
                new Segment((int)lineB.Points[0].X, (int)lineB.Points[0].Y, (int)lineB.Points[1].X, (int)lineB.Points[1].Y),
                new Segment((int)lineB.Points[1].X, (int)lineB.Points[1].Y, (int)lineB.Points[2].X, (int)lineB.Points[2].Y),
                new Segment((int)lineB.Points[2].X, (int)lineB.Points[2].Y, (int)lineB.Points[3].X, (int)lineB.Points[3].Y)
            };

            for (int i = 0; i < segmentsA.Length; i++)
            {
                for (int j = 0; j < segmentsB.Length; j++)
                {
                    if (Intersect(segmentsA[i], segmentsB[j]))
                    {
                        intersectionsTotal++;
                    }
                }
            }

            return(intersectionsTotal);
        }
        private void FilterPaths(Dictionary <Connector, List <ConnectionPath> > linkPaths)
        {
            bool isFinal;

            do
            {
                isFinal = true;
                var intersections = GetIntersectionsPerEachPath(linkPaths);

                // Choose paths with minimal intersections
                foreach (var pathList in linkPaths.Values)
                {
                    if (pathList.Count <= 1)                     // TODO: what if 0?
                    {
                        continue;
                    }
                    isFinal = false;

                    ConnectionPath maxPath          = null;
                    int            maxIntersections = 0;
                    foreach (var path in pathList)
                    {
                        if (intersections[path] >= maxIntersections)
                        {
                            maxIntersections = intersections[path];
                            maxPath          = path;
                        }
                    }
                    pathList.Remove(maxPath);
                }
            } while (!isFinal);
        }
            public int IndexOfValue(ConnectionPath value)
            {
                for (int i = 0; i < _innerList.Count; i++)
                {
                    if (_innerList[i].Value == value)
                    {
                        return(i);
                    }
                }

                throw new InvalidOperationException();
            }
        private int GetIntersectionsPerPath(ConnectionPath currentPath, Dictionary <Connector, List <ConnectionPath> > linkPaths, Connector currentLink)
        {
            int intersectionsTotal = 0;

            foreach (var link in linkPaths.Keys)
            {
                if (link == currentLink)
                {
                    continue;
                }

                var pathList = linkPaths[link];
                foreach (var path in pathList)
                {
                    intersectionsTotal += GetIntersectionsBetweenTwoPaths(currentPath, path);
                }
            }
            return(intersectionsTotal);
        }
 public void Add(int key, ConnectionPath value)
 {
     _innerList.Add(new KeyValuePair <int, ConnectionPath>(key, value));
     _innerList.Sort((x, y) => x.Key.CompareTo(y.Key));
 }
        public Polyline GetPolylineFromPath(ConnectionPath path)
        {
            var p = new Polyline()
            {
                Stroke          = Brushes.Black,    // TODO hardcode
                StrokeThickness = 2                 // TODO hardcode
            };

            Point p1 = GetPrimitiveCenter(path.PrimitiveA);
            Point p2;

            switch (path.SideA)
            {
            case Side.Left:
                p2 = GetPrimitiveLeftConnector(path.PrimitiveA);
                break;

            case Side.Right:
                p2 = GetPrimitiveRightConnector(path.PrimitiveA);
                break;

            case Side.Top:
                p2 = GetPrimitiveUpperConnector(path.PrimitiveA);
                break;

            case Side.Bottom:
                p2 = GetPrimitiveLowerConnector(path.PrimitiveA);
                break;

            default:
                throw new InvalidOperationException();
            }

            Point p4;

            if (path.IsSelfReference)
            {
                p4 = GetPrimitiveUpperConnector(path.PrimitiveA);
            }
            else
            {
                p4 = GetPrimitiveCenter(path.PrimitiveB);
            }
            Point p3;

            switch (path.SideA)
            {
            case Side.Left:
            case Side.Right:
                p3 = new Point()
                {
                    X = p2.X,
                    Y = p4.Y
                };
                break;

            case Side.Top:
            case Side.Bottom:
                p3 = new Point()
                {
                    X = p4.X,
                    Y = p2.Y
                };
                break;

            default:
                throw new InvalidOperationException();
            }

            var points = new PointCollection();

            points.Add(p1);
            points.Add(p2);
            points.Add(p3);
            points.Add(p4);
            if (path.IsSelfReference)
            {
                points.Add(GetPrimitiveCenter(path.PrimitiveB));
            }
            p.Points = points;

            return(p);
        }