Beispiel #1
0
 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);
 }
Beispiel #2
0
 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;
        }
Beispiel #6
0
        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);
        }
Beispiel #10
0
 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);
 }
Beispiel #11
0
 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);
        }
Beispiel #13
0
 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);
        }
Beispiel #15
0
 public void NullShouldThrowOverlap()
 {
     Area area1 = null;
     var area2 = new Area(new Point(11, 20), new Point(25, 25));
     area2.OverlapsWith(area1);
     Assert.Fail();
 }
Beispiel #16
0
 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);
 }
Beispiel #17
0
 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);
        }
Beispiel #21
0
 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);
 }
Beispiel #22
0
 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);
 }
Beispiel #23
0
 /// <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;
 }
Beispiel #25
0
 public void HeightShouldBeAsExpected()
 {
     var subject = new Area(new Point(1, 1), new Point(3, 3));
     double result = subject.Height;
     Assert.AreEqual(2, result);
 }
Beispiel #26
0
        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);
        }
Beispiel #27
0
 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);
 }
Beispiel #28
0
        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);
        }
Beispiel #29
0
        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);
        }
Beispiel #30
0
        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);
        }