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