public void FindPairsIntersection_SecondAndThirdPairsIntersect_ReturnsSecondPairsFirstPoint() { double firstSpotRadius = 3; double secondSpotRadius = 4; double thirdSpotRadius = 5; var firstPairFirstPoint = new TwoDimensialPoint(1.1, 1.1); var firstPairSecondPoint = new TwoDimensialPoint(1.2, 1.2); var secondPairFirstPoint = new TwoDimensialPoint(2.1, 2.1); var secondPairSecondPoint = new TwoDimensialPoint(2.2, 2.2); var thirdPairFirstPoint = new TwoDimensialPoint(3.1, 3.1); var thirdPairSecondPoint = new TwoDimensialPoint(3.2, 3.2); var firstPair = new List <TwoDimensialPoint> { firstPairFirstPoint, firstPairSecondPoint }; var secondPair = new List <TwoDimensialPoint> { secondPairFirstPoint, secondPairSecondPoint }; var thirdPair = new List <TwoDimensialPoint> { thirdPairFirstPoint, thirdPairSecondPoint }; subject.Setup(m => m.TwoCirclesIntersection(firstPairFirstPoint, secondPairFirstPoint, firstSpotRadius, secondSpotRadius)) .Returns(new List <TwoDimensialPoint>()); subject.Setup(m => m.TwoCirclesIntersection(firstPairFirstPoint, thirdPairFirstPoint, firstSpotRadius, thirdSpotRadius)) .Returns(new List <TwoDimensialPoint>()); subject.Setup(m => m.TwoCirclesIntersection(secondPairFirstPoint, thirdPairFirstPoint, secondSpotRadius, thirdSpotRadius)) .Returns(new List <TwoDimensialPoint> { new TwoDimensialPoint(), new TwoDimensialPoint() }); var result = subject.Object.FindPairsIntersection(firstPair, secondPair, thirdPair, firstSpotRadius, secondSpotRadius, thirdSpotRadius); Assert.AreEqual(secondPairFirstPoint, result); }
public void TwoCirclesIntersection_NoIntersectionsWithErrorHandling_ReturnsEmptyCollection() { double firstRadius = 3; double secondRadius = 4; int error = 5; var firstCenter = new TwoDimensialPoint { XPosition = 1, YPosition = 2 }; var secondCenter = new TwoDimensialPoint { XPosition = 4, YPosition = 8 }; double r1Minimum = firstRadius - firstRadius * error / 100; double r1Maximum = firstRadius + firstRadius * error / 100; double r2Minimum = secondRadius - secondRadius * error / 100; double r2Maximum = secondRadius + secondRadius * error / 100; subject.Setup(m => m.TwoCirclesIntersection(firstCenter, secondCenter, r1Minimum, r2Minimum)) .Returns(new List <TwoDimensialPoint>()); subject.Setup(m => m.TwoCirclesIntersection(firstCenter, secondCenter, r1Minimum, r2Maximum)) .Returns(new List <TwoDimensialPoint>()); subject.Setup(m => m.TwoCirclesIntersection(firstCenter, secondCenter, r1Maximum, r2Minimum)) .Returns(new List <TwoDimensialPoint>()); subject.Setup(m => m.TwoCirclesIntersection(firstCenter, secondCenter, r1Maximum, r2Maximum)) .Returns(new List <TwoDimensialPoint>()); var result = subject.Object.TwoCirclesIntersection(firstCenter, secondCenter, firstRadius, secondRadius, error); Assert.IsTrue(result.Count() == 0); }
/// <summary> /// Finds two circles intersection according with measurment error /// </summary> /// <param name="firstCenter">First circle's center</param> /// <param name="secondCenter">Second circle's center</param> /// <param name="r1">First circle's radius</param> /// <param name="r2">Second circle's radius</param> /// <returns>Collection of Points where cirles are intersect or empty collections when there is no intercesctions</returns> protected virtual IEnumerable <TwoDimensialPoint> TwoCirclesIntersection(TwoDimensialPoint firstCenter, TwoDimensialPoint secondCenter, double r1, double r2, int error) { double r1Minimum = r1 - r1 * error / 100; double r1Maximum = r1 + r1 * error / 100; double r2Minimum = r2 - r2 * error / 100; double r2Maximum = r2 + r2 * error / 100; var resultIntersections = TwoCirclesIntersection(firstCenter, secondCenter, r1Minimum, r2Minimum); if (resultIntersections.Count() == 2) { return(resultIntersections); } resultIntersections = TwoCirclesIntersection(firstCenter, secondCenter, r1Minimum, r2Maximum); if (resultIntersections.Count() == 2) { return(resultIntersections); } resultIntersections = TwoCirclesIntersection(firstCenter, secondCenter, r1Maximum, r2Minimum); if (resultIntersections.Count() == 2) { return(resultIntersections); } resultIntersections = TwoCirclesIntersection(firstCenter, secondCenter, r1Maximum, r2Maximum); return(resultIntersections); }
/// <summary> /// Handles clicking at the PreviewNewPointBtn button /// </summary> protected virtual void PreviewNewPointBtn_Click(object sender, RoutedEventArgs e) { if (!ValidateNewPoint()) { MessageBox.Show("New point's positions are incorrect"); return; } var tempPointsList = new List <TwoDimensialPoint>(); tempPointsList.AddRange(Points); var newPoint = new TwoDimensialPoint { Location = $"{NewPointXTxt.Text}{PublicFields.PositionSeparator}{NewPointYTxt.Text}" }; tempPointsList.Add(newPoint); var maxXValue = tempPointsList.OfType <TwoDimensialPoint>().Select(p => Math.Abs(p.XPosition)).Max(); var maxYValue = tempPointsList.OfType <TwoDimensialPoint>().Select(p => Math.Abs(p.YPosition)).Max(); // Coefficient between max value and pixels // Field's width and height are hardcoded now so 800 pixels is an effective coefficient for whole X axis var xCoefficient = 800 / 2 / maxXValue; // And 600 pixels is for Y axis var yCoefficient = 640 / 2 / maxYValue; var recalculatedPoints = ViewHelper.RecalculatePoints(tempPointsList.OfType <TwoDimensialPoint>(), xCoefficient, yCoefficient); var recalculatedNewPoint = recalculatedPoints.FirstOrDefault(p => p.Point == newPoint); XAxisSectionValueLbl.Text = $"{Math.Round(maxXValue / 4, 2)}"; YAxisSectionValueLbl.Text = $"{Math.Round(maxYValue / 4, 2)}"; //remove new point because it was used to recalculate scales recalculatedPoints.Remove(recalculatedNewPoint); ClearField(); ViewHelper.DrawRecalculatedTrajectory(DrawFieldPanel, recalculatedPoints); var newPointElement = new Ellipse { Width = 5, Height = 5, Fill = Brushes.Red }; Canvas.SetLeft(newPointElement, recalculatedNewPoint.RecalculatedX); Canvas.SetBottom(newPointElement, recalculatedNewPoint.RecalculatedY); DrawFieldPanel.Children.Add(newPointElement); }
public void GetPosition_TwoDimensialReceivers_ReturnsGetTwoDimensialPositionResult() { var getTwoDimensialPositionResultPoint = new TwoDimensialPoint(); var receivers = new List <TwoDimensialPoint> { new TwoDimensialPoint(), new TwoDimensialPoint(), new TwoDimensialPoint() }; var propogationTimes = new List <double>(); subject.Setup(m => m.GetTwoDimensialPosition(receivers, propogationTimes, 0)).Returns(getTwoDimensialPositionResultPoint); var result = subject.Object.GetPosition(receivers, propogationTimes); Assert.AreEqual(getTwoDimensialPositionResultPoint, result); }
public void TwoCirclesIntersection_WithoutIntersections_ReturnsEmptyCollection() { TwoDimensialPoint firstCenter = new TwoDimensialPoint { XPosition = 1, YPosition = 2 }; TwoDimensialPoint secondCenter = new TwoDimensialPoint { XPosition = 6, YPosition = 3 }; double firstRadius = 3; double secondRadius = 2; var intersections = subject.Object.TwoCirclesIntersection(firstCenter, secondCenter, firstRadius, secondRadius); //Expected values were calculated by online circles intersection calculator Assert.IsTrue(intersections.Count() == 0); }
public void TwoCirclesIntersection_OneIntersection_ReturnsTwoSamePositionsPoints() { TwoDimensialPoint firstCenter = new TwoDimensialPoint { XPosition = 1, YPosition = 2 }; TwoDimensialPoint secondCenter = new TwoDimensialPoint { XPosition = 6, YPosition = 2 }; double firstRadius = 3; double secondRadius = 2; var intersections = subject.Object.TwoCirclesIntersection(firstCenter, secondCenter, firstRadius, secondRadius); //Expected values were calculated by online circles intersection calculator Assert.IsTrue(intersections.Count() == 2); Assert.IsTrue(intersections.All(i => i.XPosition == 4)); Assert.IsTrue(intersections.All(i => i.YPosition == 2)); }
public void TwoCirclesIntersection_TwoIntersection_ReturnsTwoDifferentPoints() { TwoDimensialPoint firstCenter = new TwoDimensialPoint { XPosition = 1, YPosition = 2 }; TwoDimensialPoint secondCenter = new TwoDimensialPoint { XPosition = 5, YPosition = 5 }; double firstRadius = 3; double secondRadius = 4; var intersections = subject.Object.TwoCirclesIntersection(firstCenter, secondCenter, firstRadius, secondRadius); //Expected values were calculated by online circles intersection calculator Assert.IsTrue(intersections.Count() == 2); Assert.IsTrue(intersections.Any(i => i.XPosition == 3.88) && intersections.Any(i => i.XPosition == 1)); Assert.IsTrue(intersections.Any(i => i.YPosition == 1.16000000) && intersections.Any(i => i.YPosition == 5)); }
/// <summary> /// Handles clicking at the AddNewPointBtn button /// </summary> protected virtual void AddNewPointBtn_Click(object sender, RoutedEventArgs e) { if (!ValidateNewPoint()) { MessageBox.Show("New point's positions are incorrect"); return; } var newPoint = new TwoDimensialPoint { Location = $"{NewPointXTxt.Text}{PublicFields.PositionSeparator}{NewPointYTxt.Text}" }; Points.Add(newPoint); RefreshDrawPanel(); RemoveLastPointBtn.IsEnabled = true; SaveTrajectoryBtn.IsEnabled = true; }
public void TwoCirclesIntersection_WithErrorHandlingIntersectionsExists_ReturnsPointsCollection() { double firstRadius = 3; double secondRadius = 4; int error = 5; var firstCenter = new TwoDimensialPoint { XPosition = 1, YPosition = 2 }; var secondCenter = new TwoDimensialPoint { XPosition = 4, YPosition = 8 }; var intersections = new List <TwoDimensialPoint> { new TwoDimensialPoint(), new TwoDimensialPoint() }; double r1Minimum = firstRadius - firstRadius * error / 100; double r2Minimum = secondRadius - secondRadius * error / 100; subject.Setup(m => m.TwoCirclesIntersection(firstCenter, secondCenter, r1Minimum, r2Minimum)) .Returns(intersections); var result = subject.Object.TwoCirclesIntersection(firstCenter, secondCenter, firstRadius, secondRadius, error); Assert.AreEqual(intersections, result); }
/// <summary> /// ctor /// </summary> /// <param name="point">Point</param> /// <param name="x">Recalculated X position in pixels</param> /// <param name="y">Recalculated Y position in pixels</param> public DrawablePoint(TwoDimensialPoint point, double x, double y) { Point = point; RecalculatedX = x; RecalculatedY = y; }
/// <summary> /// Finds two circles intersection /// </summary> /// <param name="firstCenter">First circle's center</param> /// <param name="secondCenter">Second circle's center</param> /// <param name="r1">First circle's radius</param> /// <param name="r2">Second circle's radius</param> /// <returns>Collection of Points where cirles are intersect or empty collections when there is no intercesctions</returns> protected virtual IEnumerable <TwoDimensialPoint> TwoCirclesIntersection(TwoDimensialPoint firstCenter, TwoDimensialPoint secondCenter, double r1, double r2) { var intersections = new List <TwoDimensialPoint>(); var a1 = firstCenter.XPosition; var b1 = firstCenter.YPosition; var a2 = secondCenter.XPosition; var b2 = secondCenter.YPosition; #region MATH THEORY // // Circle equation with radius R and center placed in point (a,b): // (x-a)^2 + (y-b)^2 = R^2 // // Two circles will have common x and y values if they are intersect. // So we can create next system of equation for cirlces, // where a1 and b1 - position of first circle's center with radius R1 // and a2 and b2 - position of second circle's center with radius R2 // // { (x-a1)^2 + (y-b1)^2 = R1^2 // { (x-a2)^2 + (y-b2)^2 = R2^2 // // Open brackets and get: // // { x^2 - 2*a1*x + a1^2 + y^2 - 2*b1*y + b1^2 = R1^2 // { x^2 - 2*a2*x + a2^2 + y^2 - 2*b2*y + b2^2 = R2^2 // // Lets subtract second from the first: // // - 2*a1*x + 2*a2*x + a1^2 - a2^2 - 2*b1*y + 2*b2*y + b1^2 - b2^2 = R1^2 - R2^2 // // Express x through y: // // x = (R1^2 - R2^2 - a1^2 + a2^2 - b1^2 + b2^2)/(2*(a2 - a1)) + y*(b1 - b2)/(a2 - a1) // // Lets make a replacement // new coefficient K = (R1^2 - R2^2 - a1^2 + a2^2 - b1^2 + b2^2)/(2*(a2 - a1)) // // Then replace x with equation above into "(x-a2)^2 + (y-b2)^2 = R2^2" and get: // // K^2 + y^2*((b1 - b2)/(a2 - a1))^2 + y*2*K*(b1 - b2)/(a2 - a1) - 2*a2*K - y*2*a2*(b1 - b2)/(a2 - a1) + a2^2 + y^2 - y*2*b2 + b2^2 = R2^2 // // Calculate and join coefficients for each degree of y: // // y^2*(((b1 - b2)/(a2 - a1))^2 + 1) + y*(2*K*(b1 - b2)/(a2 - a1) - 2*a2*(b1 - b2)/(a2 - a1)-2*b2) + (K^2 - R2^2 - 2*a2*K + a2^2 + b2^2) = 0 // // Lets make next replacements to get equation with view "y^2*A + y*B + C = 0": // A = ((b1 - b2)/(a2 - a1))^2 + 1 // B = 2*K*(b1 - b2)/(a2 - a1) - 2*a2*(b1 - b2)/(a2 - a1)-2*b2 // C = K^2 - R2^2 - 2*a2*K + a2^2 + b2^2 // // Discriminant D for such type of equation is equal: // D = B^2 - 4*A*C // // So, roots of equation are: // y1 = (-B + Sqrt(D))/(2*A) // y2 = (-B - Sqrt(D))/(2*A) // // Substite this values in expression x through y and get: // x1 = K + y1*(b1 - b2)/(a2 - a1) // x2 = K + y2*(b1 - b2)/(a2 - a1) // // So we get 2 points of intersection (x1,y1) and (x2,y2) // #endregion // Coefficent K double K = (r1.Square() - r2.Square() - a1.Square() + a2.Square() - b1.Square() + b2.Square()) / (2 * (a2 - a1)); // Coefficent A double A = ((b1 - b2) / (a2 - a1)).Square() + 1; // Coefficent B double B = 2 * K * ((b1 - b2) / (a2 - a1)) - 2 * a2 * ((b1 - b2) / (a2 - a1)) - 2 * b2; // Coefficent C double C = K.Square() - r2.Square() - 2 * a2 * K + a2.Square() + b2.Square(); // Quadratic discriminant double discriminant = Math.Sqrt(B.Square() - 4 * A * C); // If there is no intersections discriminant will be NaN if (double.IsNaN(discriminant)) { return(intersections); } double Y1 = ((-1) * B + discriminant) / (2 * A); TwoDimensialPoint firstIntersection = new TwoDimensialPoint { YPosition = Math.Round(Y1, 8), XPosition = Math.Round(K + Y1 * ((b1 - b2) / (a2 - a1)), 8) }; double Y2 = ((-1) * B - discriminant) / (2 * A); TwoDimensialPoint secondIntersection = new TwoDimensialPoint { YPosition = Math.Round(Y2, 8), XPosition = Math.Round(K + Y2 * ((b1 - b2) / (a2 - a1)), 8) }; intersections.AddRange(new List <TwoDimensialPoint> { firstIntersection, secondIntersection }); return(intersections); }