public void IfThisIsNaNShouldNotThrowOverlap() { var area1 = new Area(new Point(10, 10), new Point(20, 20)); var area2 = new Area(new Point(double.NaN, 20), new Point(25, 25)); ProximityTestResult result = area2.OverlapsWith(area1); Assert.AreEqual(Proximity.NotOverlapping, result.Proximity); }
public void CentreShouldBeAsExpected() { var subject = new Area(new Point(1, 1), new Point(3, 3)); Point result = subject.Centre; Assert.AreEqual(2, result.X); Assert.AreEqual(2, result.Y); }
public void ProposePositionForAssociateShouldProposeAPositionNotOverlappingWithCentre() { ParentAssociation target = AssociationTestData.ParentAssociationIsolated(this.mockModelBuilder, this.mockType); var subjectArea = new Area(new Point(23, 45), new Point(67, 94)); Func<Area, ProximityTestResult> overlapsWithOthers = area => new ProximityTestResult(Proximity.NotOverlapping); Area result = target.ProposePosition(123.44, 553.11, new Area(new Point(23, 45), new Point(67, 94)), overlapsWithOthers); Assert.IsTrue(result.OverlapsWith(subjectArea).Proximity == Proximity.NotOverlapping); }
public void FindBestConnectionRouteShouldPointUpWhenDirectlyAbove() { var area1 = new Area(new Point(200, 200), 10, 10); // Subject var area2 = new Area(new Point(200, 0), 10, 10); this.allAreas = new[] { area1, area2 }; var route = ConnectionLine.FindBestConnectionRoute(area1, area2, IsOverlapping); route.ExitAngle.Should().BeInRange(269.9999, 270.0001); // Pointing Up route.Distance.Should().BeInRange(149.0, 149.01); }
private static Dictionary<int, Point> GetAllConnectorPoints(Area rectangle, bool isHead) { // All arrow heads are 41 units long. int leaveSpaceForArrowHead = isHead ? ArrowHead.ArrowWidth : 0; int index = 0; var connectors = new Dictionary<int, Point>(8); double oneThirdOfHeight = rectangle.Height / 3; double oneThirdOfWidth = rectangle.Width / 3; // Lower Left Point tempPoint = rectangle.TopLeft.Clone(); tempPoint.Offset(-leaveSpaceForArrowHead, oneThirdOfHeight * 2); connectors[index++] = tempPoint; // Upper Left tempPoint = rectangle.TopLeft.Clone(); tempPoint.Offset(-leaveSpaceForArrowHead, oneThirdOfHeight); connectors[index++] = tempPoint; // Left Top tempPoint = rectangle.TopLeft.Clone(); tempPoint.Offset(oneThirdOfWidth, -leaveSpaceForArrowHead); connectors[index++] = tempPoint; // Right Top tempPoint = rectangle.TopLeft.Clone(); tempPoint.Offset(oneThirdOfWidth * 2, -leaveSpaceForArrowHead); connectors[index++] = tempPoint; // Upper Right tempPoint = rectangle.BottomRight.Clone(); tempPoint.Offset(leaveSpaceForArrowHead, -oneThirdOfHeight * 2); connectors[index++] = tempPoint; // Lower Right tempPoint = rectangle.BottomRight.Clone(); tempPoint.Offset(leaveSpaceForArrowHead, -oneThirdOfHeight); connectors[index++] = tempPoint; // Right Bottom tempPoint = rectangle.BottomRight.Clone(); tempPoint.Offset(-oneThirdOfWidth * 2, leaveSpaceForArrowHead); connectors[index++] = tempPoint; // Left Bottom tempPoint = rectangle.BottomRight.Clone(); tempPoint.Offset(-oneThirdOfWidth, leaveSpaceForArrowHead); connectors[index] = tempPoint; return connectors; }
public void CanConstructUsing2Points() { double topX = 12.43, topY = 56.89; double bottomX = 45.89, bottomY = 45.87; var topPoint = new Point(topX, topY); var bottomPoint = new Point(bottomX, bottomY); var subject = new Area(topPoint, bottomPoint); // Ensure it doesnt change after creation, ie cloned. topPoint.Offset(1, 1); bottomPoint.Offset(2, 2); Assert.AreEqual(topX, subject.TopLeft.X); Assert.AreEqual(topY, subject.TopLeft.Y); Assert.AreEqual(bottomX, subject.BottomRight.X); Assert.AreEqual(bottomY, subject.BottomRight.Y); }
public ConnectionLine CalculateBestConnection(Area fromArea, Area destinationArea, Func<Area, ProximityTestResult> isOverlappingWithOtherControls) { var fromConnectors = GetAllConnectorPoints(fromArea, false); var toLineEndConnectors = GetAllConnectorPoints(destinationArea, true); var toArrowTipConnectors = GetAllConnectorPoints(destinationArea, false); // Logger.Instance.WriteEntry("Finding Best Connection Line from {0} to {1}", (fromArea.Tag ?? fromArea.TopLeft.ToString()), (destinationArea.Tag ?? destinationArea.TopLeft.ToString())); // Logger.Instance.WriteEntry(" From: {0} To: {1}", fromArea, destinationArea); double angle = fromArea.Centre.AngleToPointInDegrees(destinationArea.Centre); var idealPoint = fromArea.CalculateCircumferenceIntersectionPoint(angle); var chosenfromConnector = fromConnectors.Select(fromConnector => new Tuple<KeyValuePair<int, Point>, double>(fromConnector, fromConnector.Value.DistanceTo(idealPoint))) .OrderBy(x => x.Item2) .First(); var toConnectorsInOrderOfPreference = toLineEndConnectors.Select(toConnector => new Tuple<KeyValuePair<int, Point>, double>(toConnector, toConnector.Value.DistanceTo(idealPoint))) .OrderBy(x => x.Item2) .ToList(); // This code checks to see if the arrow head is overlapping with an existing diagram element. (not really needed) //int chosenToIndex = 0; //for (int toConnectorIndex = 0; toConnectorIndex < toConnectors.Length; toConnectorIndex++) //{ // var toConnector = toConnectorsInOrderOfPreference[toConnectorIndex]; // Area arrowheadArea = ArrowHead.GetArea(CalculateExitAngle(toConnectorIndex), toConnector.Item1); // ProximityTestResult proximityTestResult = isOverlappingWithOtherControls(arrowheadArea); // if (proximityTestResult.Proximity == Proximity.NotOverlapping || proximityTestResult.Proximity == Proximity.VeryClose) // { // chosenToIndex = toConnectorIndex; // break; // } //} return new ConnectionLine { Distance = chosenfromConnector.Item1.Value.DistanceTo(toConnectorsInOrderOfPreference[0].Item1.Value), From = chosenfromConnector.Item1.Value, To = toArrowTipConnectors[toConnectorsInOrderOfPreference[0].Item1.Key], // toConnectorsInOrderOfPreference[0].Item1.Value, // Incorrect ToLineEnd = toConnectorsInOrderOfPreference[0].Item1.Value, ExitAngle = CalculateExitAngle(toConnectorsInOrderOfPreference[0].Item1.Key) }; }
/// <summary> /// Calculate the best line connecting <see cref="fromArea"/> to <see cref="destinationArea"/> /// </summary> /// <param name="fromArea"> /// The from Area. /// </param> /// <param name="destinationArea"> /// The destination Area. /// </param> /// <param name="isOverlappingWithOtherControls"> /// The is Overlapping With Other Controls. /// </param> /// <returns> /// The <see cref="ConnectionLine"/>. /// </returns> public ConnectionLine CalculateBestConnection(Area fromArea, Area destinationArea, Func<Area, ProximityTestResult> isOverlappingWithOtherControls) { double fromAngle = fromArea.Centre.AngleToPointInDegrees(destinationArea.Centre); Point fromIdealPoint = fromArea.CalculateCircumferenceIntersectionPoint(fromAngle); double toAngle = TrigHelper.InverseAngle(fromAngle); Point toIdealPoint = destinationArea.CalculateCircumferenceIntersectionPoint(toAngle); Point toLineEnd = toIdealPoint; // Leave room for arrow head double offset1 = (ArrowHead.ArrowWidth - 2) * Math.Sin(CalculateLineAngleToPreviousAxis(toAngle)); double offset2 = (ArrowHead.ArrowWidth - 2) * Math.Cos(CalculateLineAngleToPreviousAxis(toAngle)); if (toAngle >= 0 && toAngle < 90) { toLineEnd.Offset(offset1, -offset2); } else if (toAngle >= 90 && toAngle <= 180) { toLineEnd.Offset(offset2, offset1); } else if (toAngle > 180 && toAngle < 270) { toLineEnd.Offset(-offset1, offset2); } else { toLineEnd.Offset(-offset2, -offset1); } return new ConnectionLine { Distance = fromIdealPoint.DistanceTo(toIdealPoint), ExitAngle = CalculateExitAngle(fromAngle), From = fromIdealPoint, To = toIdealPoint, ToLineEnd = toLineEnd, ToAngle = toAngle, FromAngle = fromAngle, }; }
public void FindBestConnectionRouteShouldPointUpWhenSlightlyToLeft() { var area1 = new Area(new Point(200, 200), 30, 30); // Subject var area2 = new Area(new Point(149, 0), 30, 30); this.allAreas = new[] { area1, area2 }; var route = ConnectionLine.FindBestConnectionRoute(area1, area2, IsOverlapping); route.ExitAngle.Should().BeInRange(269.9999, 270.0001); // Pointing Up route.Distance.Should().BeInRange(135.35, 135.36); }
public void ShouldBeVeryCloseAndBeUp() { var area1 = new Area(new Point(0, 0), new Point(5, 5)); var area2 = new Area(new Point(0, 10), new Point(5, 15)); ProximityTestResult result = area2.OverlapsWith(area1); Assert.AreEqual(Direction.Up, result.DirectionToOtherObject); Assert.AreEqual(Proximity.VeryClose, result.Proximity); }
public void ShouldBeVeryCloseTouching() { var area1 = new Area(new Point(10, 10), new Point(20, 20)); var area2 = new Area(new Point(10, 20), new Point(25, 25)); Assert.AreEqual(Proximity.VeryClose, area2.OverlapsWith(area1).Proximity); }
public void ProposePositionForAssociateShouldProposeAPositionNotOverlappingWithCentre() { this.mockDimensions.Expect(m => m.CalculateNextAvailableAngle()).Return(33.33); FieldAssociation target = AssociationTestData.FieldAssociationFullModel(this.factory, typeof(string), new[] { "name" }, 3, this.mockDimensions); var subjectArea = new Area(new Point(23, 45), new Point(67, 94)); Func<Area, ProximityTestResult> overlapsWithOthers = area => new ProximityTestResult(Proximity.NotOverlapping); Area result = target.ProposePosition( 123.44, 553.11, new Area(new Point(23, 45), new Point(67, 94)), overlapsWithOthers); Assert.IsTrue(result.OverlapsWith(subjectArea).Proximity == Proximity.NotOverlapping); }
public void ShouldBeVeryCloseAndBeToTheRight() { var area1 = new Area(new Point(10, 20), new Point(15, 25)); var area2 = new Area(new Point(20, 20), new Point(25, 25)); ProximityTestResult result = area1.OverlapsWith(area2); Assert.AreEqual(Direction.Right, result.DirectionToOtherObject); Assert.AreEqual(Proximity.VeryClose, result.Proximity); }
/// <summary> /// Proposes a new position given the input parameters. /// </summary> /// <param name="actualWidth"> /// The actual width. /// </param> /// <param name="actualHeight"> /// The actual height. /// </param> /// <param name="subjectArea"> /// The subject area. /// </param> /// <param name="overlapsWithOthers"> /// The overlaps with others. /// </param> /// <returns> /// The <see cref="Area"/>. that represents the new position. /// </returns> /// <exception cref="ArgumentNullResourceException"> /// Will be thrown if <see cref="subjectArea"/> is null. /// </exception> public override Area ProposePosition(double actualWidth, double actualHeight, Area subjectArea, Func<Area, ProximityTestResult> overlapsWithOthers) { if (!this.IsInitialised) { CannotUseWithoutInitializationFirst(); } if (subjectArea == null) { throw new ArgumentNullResourceException("subjectArea", Resources.General_Given_Parameter_Cannot_Be_Null); } return this.GetProposedAreaSemiCircle(actualWidth, actualHeight, subjectArea.Centre, overlapsWithOthers); }
public void NullShouldThrowOverlap() { Area area1 = null; var area2 = new Area(new Point(11, 20), new Point(25, 25)); area2.OverlapsWith(area1); Assert.Fail(); }
public void ShouldOverlap() { var area1 = new Area(new Point(10, 10), new Point(20, 20)); var area2 = new Area(new Point(15, 15), new Point(25, 25)); Assert.AreEqual(Proximity.Overlapping, area2.OverlapsWith(area1).Proximity); }
public void ShouldNotOverlapAndBeToTheRight() { var area1 = new Area(new Point(10, 20), new Point(15, 25)); var area2 = new Area(new Point(55, 20), new Point(60, 25)); ProximityTestResult result = area1.OverlapsWith(area2); result.Proximity.Should().Be(Proximity.VeryClose); }
private Area GetProposedAreaSemiCircle(double actualWidth, double actualHeight, Point centre, Func<Area, ProximityTestResult> overlapsWithOthers) { // A angle of 0 degrees in this context is moving directly to the right this.angle = this.dimensions.CalculateNextAvailableAngle(); Area proposedArea; var calc = new CircleCalculator(centre, this.angle); double radius = 250; ProximityTestResult proximityResult = null; do { if (proximityResult != null && proximityResult.Proximity == Proximity.VeryClose) { radius += LayoutConstants.MinimumDistanceBetweenObjects / 2; } else { radius += LayoutConstants.MinimumDistanceBetweenObjects; } proposedArea = new Area(calc.CalculatePointOnCircle(radius), actualWidth, actualHeight); proposedArea = proposedArea.OffsetToMakeTopLeftCentre(); proximityResult = overlapsWithOthers(proposedArea); } while (proximityResult.Proximity == Proximity.Overlapping || proximityResult.Proximity == Proximity.VeryClose); return proposedArea; }
private ProximityTestResult IsOverlapping(Area proposedArea) { List<ProximityTestResult> proximities = this.allAreas.Select(x => x.OverlapsWith(proposedArea)).ToList(); bool overlapsWith = proximities.Any(result => result.Proximity == Proximity.Overlapping); if (overlapsWith) { return new ProximityTestResult(Proximity.Overlapping); } var veryClose = proximities.Where(x => x.Proximity == Proximity.VeryClose).OrderBy(x => x.DistanceToClosestObject); if (veryClose.Any()) { return veryClose.First(); } return new ProximityTestResult(Proximity.NotOverlapping); }
public void FindBestConnectionRouteShouldPointUpWhenSlightlyToLeftAndClose() { var area1 = new Area(new Point(667.377, 232.822), new Point(818.377, 429.153)) { Tag = "Subject" }; // Subject var area2 = new Area(new Point(667.377, 0), new Point(826.937, 130.322)) { Tag = "Area2" }; // Directly above subject (667.37715347279,0) (826.93715347279,130.322792358398) var area3 = new Area(new Point(476.377, 0), new Point(627.377, 130.322)) { Tag = "Area3" }; // To the left and above subject this.allAreas = new[] { area1, area2, area3 }; var route = ConnectionLine.FindBestConnectionRoute(area1, area3, IsOverlapping); route.ExitAngle.Should().BeInRange(269.9999, 270.0001); // Pointing Up route.Distance.Should().BeInRange(153.52, 153.53); }
public void ShouldNotOverlapAndBeUp() { var area1 = new Area(new Point(20, 0), new Point(25, 5)); var area2 = new Area(new Point(20, 45.1), new Point(25, 65.1)); ProximityTestResult result = area2.OverlapsWith(area1); result.Proximity.Should().Be(Proximity.VeryClose); }
public void DistanceToPointShouldBeAsExpected() { var subject = new Area(new Point(1, 1), new Point(3, 3)); double result = subject.DistanceToPoint(new Point(10, 10)); Assert.AreEqual(12.72792, result, 0.00001); }
/// <summary> /// Proposes a position for the associate. /// </summary> /// <param name="actualWidth"> /// The actual width of the associate UI element. /// </param> /// <param name="actualHeight"> /// The actual height of the associate UI element. /// </param> /// <param name="subjectArea"> /// The subject area. /// </param> /// <param name="overlapsWithOthers"> /// The function delegate that determines if the proposed area overlaps with others. /// </param> /// <returns> /// The <see cref="Area"/>. /// </returns> public abstract Area ProposePosition(double actualWidth, double actualHeight, Area subjectArea, Func<Area, ProximityTestResult> overlapsWithOthers);
public override Area ProposePosition(double actualWidth, double actualHeight, Area subjectArea, Func<Area, ProximityTestResult> overlapsWithOthers) { return subjectArea; }
public void HeightShouldBeAsExpected() { var subject = new Area(new Point(1, 1), new Point(3, 3)); double result = subject.Height; Assert.AreEqual(2, result); }
public void OffSetShouldNotReassignReference() { var subject = new Area(new Point(12.34, 45.56), new Point(67.67, 89.90)); Area result = subject.Offset(1, 1); // Ensure it doesnt change after creation, ie cloned. subject.Offset(1, 1); Assert.AreNotEqual(result.TopLeft, subject.TopLeft); Assert.AreNotEqual(result.BottomRight, subject.BottomRight); }
public void NaNShouldThrowOverlap() { var area1 = new Area(new Point(double.NaN, 10), new Point(20, 20)); var area2 = new Area(new Point(11, 20), new Point(25, 25)); area2.OverlapsWith(area1); }
public void OffsetToCentreMustMoveToCentre() { var subject = new Area(new Point(12.34, 45.56), new Point(67.67, 89.90)); Area result = subject.OffsetToMakeTopLeftCentre(); Assert.AreEqual(result.Centre, subject.TopLeft); }
public void OffSetShouldMoveAsExpected() { var subject = new Area(new Point(12.34, 45.56), new Point(67.67, 89.90)); Area result = subject.Offset(1, 1); Assert.AreEqual(13.34, result.TopLeft.X); Assert.AreEqual(46.56, result.TopLeft.Y); Assert.AreEqual(68.67, result.BottomRight.X); Assert.AreEqual(90.90, result.BottomRight.Y); }
public void OffsetToCentreMustNotReassignReference() { var subject = new Area(new Point(12.34, 45.56), new Point(67.67, 89.90)); Area result = subject.OffsetToMakeTopLeftCentre(); Assert.AreNotEqual(subject.TopLeft, result.TopLeft); }