예제 #1
0
        public bool Deserialize(IParser reader, Type expectedType, Func <IParser, Type, object> nestedObjectDeserializer, out object value)
        {
            if (expectedType != typeof(OrthogonalLine))
            {
                value = null;
                return(false);
            }

            var valueObject = nestedObjectDeserializer(reader, typeof(List <IntVector2>));

            if (valueObject == null)
            {
                throw new ParsingException($"Given element could not be parsed into {nameof(OrthogonalLine)}.");
            }

            var intVector2List = (List <IntVector2>)valueObject;

            if (intVector2List.Count != 2)
            {
                throw new ParsingException($"Given element could not be parsed into {nameof(OrthogonalLine)}. There must be exactly 2 elements of type {nameof(IntVector2)} in the array.");
            }

            value = new OrthogonalLine(intVector2List[0], intVector2List[1]);
            return(true);
        }
예제 #2
0
            public bool Intersect(OrthogonalLine line, out int x, out int y)
            {
                x = 0;
                y = 0;

                bool intersect = false;

                if (line.FromX != line.ToX)
                {
                    x         = this.FromX;
                    intersect = line.FromX < this.FromX && this.FromX < line.ToX;
                }
                else
                {
                    x         = line.FromX;
                    intersect = this.FromX < line.FromX && line.FromX < this.ToX;
                }
                if (!intersect)
                {
                    return(false);
                }

                if (line.FromY != line.ToY)
                {
                    y         = this.FromY;
                    intersect = line.FromY < this.FromY && this.FromY < line.ToY;
                }
                else
                {
                    y         = line.FromY;
                    intersect = this.FromY < line.FromY && line.FromY < this.ToY;
                }
                return(intersect);
            }
        /// <summary>
        /// Returns a list of lines obtained by removing all the intersections from the original line.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="intersection"></param>
        /// <returns></returns>
        private List <OrthogonalLine> PartitionByIntersection(OrthogonalLine line, IList <OrthogonalLine> intersection)
        {
            var result              = new List <OrthogonalLine>();
            var rotation            = line.ComputeRotation();
            var rotatedLine         = line.Rotate(rotation, true);
            var directionVector     = rotatedLine.GetDirectionVector();
            var rotatedIntersection = intersection.Select(x => x.Rotate(rotation, false).GetNormalized()).ToList();

            rotatedIntersection.Sort((x1, x2) => x1.From.CompareTo(x2.From));

            var lastPoint = rotatedLine.From - directionVector;

            foreach (var intersectionLine in rotatedIntersection)
            {
                if (intersectionLine.From != lastPoint && intersectionLine.From - directionVector != lastPoint)
                {
                    result.Add(new OrthogonalLine(lastPoint + directionVector, intersectionLine.From - directionVector));
                }

                lastPoint = intersectionLine.To;
            }

            if (rotatedLine.To != lastPoint && rotatedLine.To - directionVector != lastPoint)
            {
                result.Add(new OrthogonalLine(lastPoint + directionVector, rotatedLine.To));
            }

            return(result.Select(x => x.Rotate(-rotation, false)).ToList());
        }
        public void OverlapAlongLine_ComplexCase()
        {
            var p1 = GetPlusShape();
            var p2 = new GridPolygonBuilder()
                     .AddPoint(0, 0)
                     .AddPoint(0, 8)
                     .AddPoint(8, 8)
                     .AddPoint(8, 2)
                     .AddPoint(6, 2)
                     .AddPoint(6, 6)
                     .AddPoint(2, 6)
                     .AddPoint(2, 0)
                     .Build();

            var line = new OrthogonalLine(new IntVector2(0, -2), new IntVector2(15, -2));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <IntVector2, bool> >()
            {
                Tuple.Create(new IntVector2(0, -2), true),
                Tuple.Create(new IntVector2(2, -2), false),
                Tuple.Create(new IntVector2(3, -2), true),
                Tuple.Create(new IntVector2(6, -2), false),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
 public DoorInfo(OrthogonalLine doorLine, Vector2Int facingDirection, TRoom connectedRoom)
 {
     DoorLine        = doorLine;
     FacingDirection = facingDirection;
     ConnectedRoom   = connectedRoom;
     IsHorizontal    = FacingDirection == Vector2Int.up || FacingDirection == Vector2Int.down;
 }
        public void Contains_Outside_ReturnsMinusOne()
        {
            {
                var line  = new OrthogonalLine(new IntVector2(4, 2), new IntVector2(10, 2));
                var point = new IntVector2(3, 2);

                // TODO: why is it on the polygon?
                foreach (var rotation in GridPolygon.PossibleRotations)
                {
                    var rotatedLine  = line.Rotate(rotation);
                    var rotatedPoint = point.RotateAroundCenter(rotation);

                    var actualIndex = rotatedLine.Contains(rotatedPoint);

                    Assert.AreEqual(-1, actualIndex);
                }
            }

            {
                var line  = new OrthogonalLine(new IntVector2(4, 2), new IntVector2(10, 2));
                var point = new IntVector2(12, 2);

                // TODO: why is it on the polygon?
                foreach (var rotation in GridPolygon.PossibleRotations)
                {
                    var rotatedLine  = line.Rotate(rotation);
                    var rotatedPoint = point.RotateAroundCenter(rotation);

                    var actualIndex = rotatedLine.Contains(rotatedPoint);

                    Assert.AreEqual(-1, actualIndex);
                }
            }
        }
        private void HandleDeleteDoors()
        {
            var doors      = target as Doors;
            var gameObject = doors.transform.gameObject;
            var e          = Event.current;

            var tilePosition = GetCurrentTilePosition();

            // Make sure that the current active object in the inspector is not deselected
            Selection.activeGameObject = gameObject;
            var controlId = GUIUtility.GetControlID(FocusType.Passive);

            HandleUtility.AddDefaultControl(controlId);

            if (e.type == EventType.MouseUp)
            {
                for (int i = doors.DoorsList.Count - 1; i >= 0; i--)
                {
                    var door           = doors.DoorsList[i];
                    var orthogonalLine = new OrthogonalLine(door.From.RoundToUnityIntVector3(), door.To.RoundToUnityIntVector3());

                    if (orthogonalLine.Contains(tilePosition) != -1)
                    {
                        Undo.RecordObject(target, "Deleted door position");
                        doors.DoorsList.RemoveAt(i);
                        EditorUtility.SetDirty(target);
                    }
                }

                Event.current.Use();
            }
        }
        public void Rotate_InvalidDegrees_Throws()
        {
            var line = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(5, 0));

            Assert.Throws <ArgumentException>(() => line.Rotate(1));
            Assert.Throws <ArgumentException>(() => line.Rotate(15));
            Assert.Throws <ArgumentException>(() => line.Rotate(-181));
        }
예제 #9
0
 public DoorInstance(OrthogonalLine doorLine, Vector2Int facingDirection, RoomBase connectedRoom, RoomInstance connectedRoomInstance)
 {
     this.doorLine              = doorLine;
     this.facingDirection       = facingDirection;
     this.connectedRoom         = connectedRoom;
     this.connectedRoomInstance = connectedRoomInstance;
     this.isHorizontal          = FacingDirection == Vector2Int.up || FacingDirection == Vector2Int.down;
 }
        public void OverlapAlongLine_Rectangles_OverlapStart2()
        {
            var p1   = GridPolygon.GetSquare(5);
            var p2   = GridPolygon.GetRectangle(2, 3) + new IntVector2(0, -3);
            var line = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(0, 10));

            var result = polygonOverlap.OverlapAlongLine(p1, p2, line);

            Assert.AreEqual(0, result.Count);
        }
        public void GetDirection_ReturnsDirection()
        {
            var top    = new OrthogonalLine(new IntVector2(2, 2), new IntVector2(2, 4));
            var bottom = new OrthogonalLine(new IntVector2(2, 4), new IntVector2(2, 2));
            var right  = new OrthogonalLine(new IntVector2(5, 3), new IntVector2(8, 3));
            var left   = new OrthogonalLine(new IntVector2(8, 3), new IntVector2(5, 3));

            Assert.AreEqual(OrthogonalLine.Direction.Top, top.GetDirection());
            Assert.AreEqual(OrthogonalLine.Direction.Bottom, bottom.GetDirection());
            Assert.AreEqual(OrthogonalLine.Direction.Right, right.GetDirection());
            Assert.AreEqual(OrthogonalLine.Direction.Left, left.GetDirection());
        }
        public void GetPoints_Bottom_ReturnsPoints()
        {
            var line           = new OrthogonalLine(new IntVector2(2, 4), new IntVector2(2, 2));
            var expectedPoints = new List <IntVector2>()
            {
                new IntVector2(2, 4),
                new IntVector2(2, 3),
                new IntVector2(2, 2),
            };

            Assert.IsTrue(line.GetPoints().SequenceEqual(expectedPoints));
        }
        public void Shrink_Invalid_Throws()
        {
            {
                var line = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(5, 0));
                Assert.Throws <ArgumentException>(() => line.Shrink(3));
            }

            {
                var line = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(-6, 0));
                Assert.Throws <ArgumentException>(() => line.Shrink(4, 3));
            }
        }
        public void GetPoints_Left_ReturnsPoints()
        {
            var line           = new OrthogonalLine(new IntVector2(8, 3), new IntVector2(5, 3));
            var expectedPoints = new List <IntVector2>()
            {
                new IntVector2(8, 3),
                new IntVector2(7, 3),
                new IntVector2(6, 3),
                new IntVector2(5, 3),
            };

            Assert.IsTrue(line.GetPoints().SequenceEqual(expectedPoints));
        }
        public void OverlapAlongLine_Rectangles_OverlapEnd()
        {
            var p1   = GridPolygon.GetSquare(5);
            var p2   = GridPolygon.GetRectangle(2, 3) + new IntVector2(0, 8);
            var line = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(0, 10));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <IntVector2, bool> >()
            {
                Tuple.Create(new IntVector2(0, 4), true),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
        public void OverlapAlongLine_LAndL3()
        {
            var p1   = GetLShape();
            var p2   = GetLShape();
            var line = new OrthogonalLine(new IntVector2(3, 5), new IntVector2(3, -2));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <IntVector2, bool> >()
            {
                Tuple.Create(new IntVector2(3, 2), true),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
        private void DrawDoor(Grid grid, Vector3Int from, Vector3Int to)
        {
            var length   = new OrthogonalLine(from, to).Length;
            var doorLine = new DoorLineGrid2D()
            {
                From   = from,
                To     = to,
                Length = length,
            };

            var color = Color.red;

            DoorsInspectorUtils.DrawDoorLine(doorLine, grid, color);
        }
        public void OverlapAlongLine_SquareAndL()
        {
            var p1   = GridPolygon.GetSquare(6);
            var p2   = GetLShape();
            var line = new OrthogonalLine(new IntVector2(-2, 3), new IntVector2(5, 3));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <IntVector2, bool> >()
            {
                Tuple.Create(new IntVector2(-2, 3), true),
                Tuple.Create(new IntVector2(3, 3), false),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
        protected override void RemoveDoor(Vector3Int position)
        {
            for (int i = doors.ManualDoorModeData.DoorsList.Count - 1; i >= 0; i--)
            {
                var door           = doors.ManualDoorModeData.DoorsList[i];
                var orthogonalLine = new OrthogonalLine(door.From.RoundToUnityIntVector3(), door.To.RoundToUnityIntVector3());

                if (orthogonalLine.Contains(position) != -1)
                {
                    Undo.RecordObject(doors, "Deleted door position");
                    doors.ManualDoorModeData.DoorsList.RemoveAt(i);
                    EditorUtility.SetDirty(doors);
                }
            }
        }
        protected override void RemoveDoor(Vector3Int position)
        {
            for (int i = doors.HybridDoorModeData.DoorLines.Count - 1; i >= 0; i--)
            {
                var door           = doors.HybridDoorModeData.DoorLines[i];
                var orthogonalLine = new OrthogonalLine(door.From, door.To);

                if (orthogonalLine.Contains(position) != -1)
                {
                    Undo.RecordObject(doors, "Deleted door position");
                    doors.HybridDoorModeData.DoorLines.RemoveAt(i);
                    EditorUtility.SetDirty(doors);
                }
            }
        }
        public void Rotate_ReturnsRotated()
        {
            {
                var line     = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(5, 0));
                var expected = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(0, -5));
                Assert.AreEqual(expected, line.Rotate(90));
                Assert.AreEqual(expected, line.Rotate(-270));
            }

            {
                var line     = new OrthogonalLine(new IntVector2(-2, -2), new IntVector2(-2, 5));
                var expected = new OrthogonalLine(new IntVector2(2, 2), new IntVector2(2, -5));
                Assert.AreEqual(expected, line.Rotate(180));
                Assert.AreEqual(expected, line.Rotate(-180));
            }
        }
예제 #22
0
        public void TryGetIntersection_HorizontalAndVertical()
        {
            {
                // No intersection - one above the other
                var line1 = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1));
                var line2 = new OrthogonalLine(new IntVector2(3, 2), new IntVector2(3, 7));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
            }

            {
                // No intersection - one next to the other
                var line1 = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1));
                var line2 = new OrthogonalLine(new IntVector2(6, 2), new IntVector2(6, 7));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));

                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.IsFalse(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
            }

            {
                // Intersection is one point
                var line1    = new OrthogonalLine(new IntVector2(1, 1), new IntVector2(5, 1));
                var line2    = new OrthogonalLine(new IntVector2(3, -2), new IntVector2(3, 5));
                var expected = new OrthogonalLine(new IntVector2(3, 1), new IntVector2(3, 1));

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line1, line2, out var intersection1));
                Assert.AreEqual(expected, intersection1);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line1.SwitchOrientation(), line2.SwitchOrientation(), out var intersection2));
                Assert.AreEqual(expected, intersection2);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line2, line1, out var intersection3));
                Assert.AreEqual(expected, intersection3);

                Assert.IsTrue(orthogonalLineIntersection.TryGetIntersection(line2.SwitchOrientation(), line1.SwitchOrientation(), out var intersection4));
                Assert.AreEqual(expected, intersection4);
            }
        }
        public void Shrink_Valid_ReturnsShrinked()
        {
            {
                var line     = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(5, 0));
                var expected = new OrthogonalLine(new IntVector2(1, 0), new IntVector2(3, 0));
                var shrinked = line.Shrink(1, 2);

                Assert.AreEqual(expected, shrinked);
            }

            {
                var line     = new OrthogonalLine(new IntVector2(0, 0), new IntVector2(0, 6));
                var expected = new OrthogonalLine(new IntVector2(0, 2), new IntVector2(0, 5));
                var shrinked = line.Shrink(2, 1);

                Assert.AreEqual(expected, shrinked);
            }
        }
예제 #24
0
        /// <summary>
        /// Transform door line according to a given transformation.
        /// </summary>
        /// <param name="doorLine"></param>
        /// <param name="transformation"></param>
        /// <returns></returns>
        public static IDoorLine TransformDoorLine(IDoorLine doorLine, Transformation transformation)
        {
            var doorPosition = doorLine.Line;

            if (doorPosition.GetDirection() == OrthogonalLine.Direction.Undefined)
            {
                throw new InvalidOperationException("Cannot fix door direction when original direction is undefined");
            }

            switch (transformation)
            {
            case Transformation.Identity:
                return(doorLine);

            case Transformation.Rotate90:
                return(new DoorLine(doorPosition.Rotate(90), doorLine.Length));

            case Transformation.Rotate180:
                return(new DoorLine(doorPosition.Rotate(180), doorLine.Length));

            case Transformation.Rotate270:
                return(new DoorLine(doorPosition.Rotate(270), doorLine.Length));
            }

            // Other transformations need to switch door directions
            var firstStartPoint      = doorPosition.From.Transform(transformation);
            var lastStartPoint       = doorPosition.To.Transform(transformation);
            var length               = doorLine.Length;
            var transformedDirection = TransformDirection(doorPosition.GetDirection(), transformation);
            var transformedLine      = new OrthogonalLine(firstStartPoint, lastStartPoint, transformedDirection);

            var lastEndPoint = lastStartPoint + length * transformedLine.GetDirectionVector();

            var newDirection    = OrthogonalLine.GetOppositeDirection(transformedDirection);
            var newDoorPosition = new OrthogonalLine(lastEndPoint, lastEndPoint + transformedLine.Length * transformedLine.SwitchOrientation().GetDirectionVector(), newDirection);

            if (newDoorPosition.Length != doorPosition.Length)
            {
                throw new InvalidOperationException();
            }

            return(new DoorLine(newDoorPosition, doorLine.Length));
        }
        public void OverlapAlongLine_LAndL2()
        {
            var p1 = GetLShape();
            var p2 = new GridPolygonBuilder()
                     .AddPoint(0, 0)
                     .AddPoint(0, 9)
                     .AddPoint(3, 9)
                     .AddPoint(3, 3)
                     .AddPoint(6, 3)
                     .AddPoint(6, 0)
                     .Build();
            var line = new OrthogonalLine(new IntVector2(3, 8), new IntVector2(3, -2));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <IntVector2, bool> >()
            {
                Tuple.Create(new IntVector2(3, 2), true),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
예제 #26
0
        private DoorLine GetDoorLine(GridPolygon polygon, OrthogonalLine doorPosition)
        {
            if (doorPosition.Length == 0)
            {
                throw new InvalidOperationException();
            }

            foreach (var side in polygon.GetLines())
            {
                if (side.Contains(doorPosition.From) == -1 || side.Contains(doorPosition.To) == -1)
                {
                    continue;
                }

                var isGoodDirection = doorPosition.From + doorPosition.Length * side.GetDirectionVector() == doorPosition.To;
                var from            = isGoodDirection ? doorPosition.From : doorPosition.To;

                return(new DoorLine(new OrthogonalLine(from, from, side.GetDirection()), doorPosition.Length));
            }

            throw new InvalidOperationException("Given door position is not on any side of the polygon");
        }
        public void OverlapAlongLine_SquareAndL3()
        {
            var p1 = GridPolygon.GetSquare(6);
            var p2 = new GridPolygonBuilder()
                     .AddPoint(0, 0)
                     .AddPoint(0, 6)
                     .AddPoint(6, 6)
                     .AddPoint(6, 3)
                     .AddPoint(3, 3)
                     .AddPoint(3, 0)
                     .Build();
            var line = new OrthogonalLine(new IntVector2(3, 2), new IntVector2(3, -5));

            var result   = polygonOverlap.OverlapAlongLine(p1, p2, line);
            var expected = new List <Tuple <IntVector2, bool> >()
            {
                Tuple.Create(new IntVector2(3, 2), true),
                Tuple.Create(new IntVector2(3, -3), false),
            };

            Assert.IsTrue(expected.SequenceEqual(result));
        }
        public void GetConfigurationSpace_OverlapOne()
        {
            var p1 = GridPolygon.GetSquare(3);
            var p2 = GridPolygon.GetSquare(5);

            var configurationSpace = generator.GetConfigurationSpace(p1, new OverlapMode(1, 1), p2, new OverlapMode(1, 1));
            var expectedPoints     = new List <IntVector2>();
            var actualPoints       = configurationSpace.Lines.Select(x => x.GetPoints()).SelectMany(x => x).ToList();

            {
                // Top side of fixed
                var points = new OrthogonalLine(new IntVector2(0, 5), new IntVector2(2, 5)).GetPoints();
                expectedPoints.AddRange(points);
                Assert.AreEqual(points.Count, actualPoints.Intersect(points).Count());
            }

            {
                // Bottom side of fixed
                var points = new OrthogonalLine(new IntVector2(0, -3), new IntVector2(2, -3)).GetPoints();
                expectedPoints.AddRange(points);
                Assert.AreEqual(points.Count, actualPoints.Intersect(points).Count());
            }

            {
                // Right side of fixed
                var points = new OrthogonalLine(new IntVector2(5, 2), new IntVector2(5, 0)).GetPoints();
                expectedPoints.AddRange(points);
                Assert.AreEqual(points.Count, actualPoints.Intersect(points).Count());
            }

            {
                // Left side of fixed
                var points = new OrthogonalLine(new IntVector2(-3, 0), new IntVector2(-3, 2)).GetPoints();
                expectedPoints.AddRange(points);
                Assert.AreEqual(points.Count, actualPoints.Intersect(points).Count());
            }

            Assert.AreEqual(expectedPoints.Distinct().Count(), actualPoints.Count);
        }
        private IEnumerable <IDoorLine> GetDoorLine(GridPolygon polygon, OrthogonalLine doorPosition)
        {
            var found = false;

            foreach (var side in polygon.GetLines())
            {
                if (side.Contains(doorPosition.From) == -1 || side.Contains(doorPosition.To) == -1)
                {
                    continue;
                }

                var isGoodDirection = doorPosition.From + doorPosition.Length * side.GetDirectionVector() == doorPosition.To;
                var from            = isGoodDirection ? doorPosition.From : doorPosition.To;

                found = true;
                yield return(new DoorLine(new OrthogonalLine(from, from, side.GetDirection()), doorPosition.Length));
            }

            if (found == false)
            {
                throw new InvalidOperationException("Given door position is not on any side of the polygon");
            }
        }
예제 #30
0
        /// <summary>
        /// Merges two lists of events.
        /// </summary>
        /// <param name="events1"></param>
        /// <param name="events2"></param>
        /// <param name="line"></param>
        /// <returns></returns>
        protected List <Tuple <IntVector2, bool> > MergeEvents(List <Tuple <IntVector2, bool> > events1, List <Tuple <IntVector2, bool> > events2, OrthogonalLine line)
        {
            if (events1.Count == 0)
            {
                return(events2);
            }

            if (events2.Count == 0)
            {
                return(events1);
            }

            var merged = new List <Tuple <IntVector2, bool> >();

            var counter1 = 0;
            var counter2 = 0;

            var lastOverlap = false;
            var overlap1    = false;
            var overlap2    = false;

            // Run the main loop while both lists still have elements
            while (counter1 < events1.Count && counter2 < events2.Count)
            {
                var pair1 = events1[counter1];
                var pos1  = line.Contains(pair1.Item1);

                var pair2 = events2[counter2];
                var pos2  = line.Contains(pair2.Item1);

                if (pos1 <= pos2)
                {
                    overlap1 = pair1.Item2;
                    counter1++;
                }

                if (pos1 >= pos2)
                {
                    overlap2 = pair2.Item2;
                    counter2++;
                }

                var overlap = overlap1 || overlap2;

                if (overlap != lastOverlap)
                {
                    if (pos1 < pos2)
                    {
                        merged.Add(Tuple.Create(pair1.Item1, overlap));
                    }
                    else
                    {
                        merged.Add(Tuple.Create(pair2.Item1, overlap));
                    }
                }

                lastOverlap = overlap;
            }

            // Add remaining elements from the first list
            if (events2.Last().Item2 != true)
            {
                while (counter1 < events1.Count)
                {
                    var pair = events1[counter1];

                    if (merged.Last().Item2 != pair.Item2)
                    {
                        merged.Add(pair);
                    }

                    counter1++;
                }
            }

            // Add remaining elements from the second list
            if (events1.Last().Item2 != true)
            {
                while (counter2 < events2.Count)
                {
                    var pair = events2[counter2];

                    if (merged.Last().Item2 != pair.Item2)
                    {
                        merged.Add(pair);
                    }

                    counter2++;
                }
            }

            return(merged);
        }