protected override DropOnEdge CheckSquere(int a, int b, SquareMatrixBase square_matrix, DropOnEdge result) { var s_matrix = square_matrix as SquareMatrixEdges; if (s_matrix == null) { throw new ArgumentException(nameof(square_matrix)); } if (a < 0 || a >= s_matrix.SizeX || b < 0 || b >= s_matrix.SizeY) { return(result); } double curDistance = result.L; IRoad curRoad = result.Edge; IPoint curPointTo = result.Point_To; bool curDropNodeFlag = result.DropNodeFlag; double curA = 0, curB = 0, curC = 0; if (result.Edge != null) { curA = result.Edge.A; curB = result.Edge.B; curC = result.Edge.C; } if (s_matrix.Matrix[a, b] != null) { foreach (var road in s_matrix.Matrix[a, b]) { DropOnEdge temp = fun_set.heuristic_between_point_and_line(result.Point_From, road); if (temp.L <= curDistance && temp.Edge.Finish != temp.Point_To) { if (temp.IsRightTurn) { curDistance = temp.L; curRoad = temp.Edge; curPointTo = temp.Point_To; curDropNodeFlag = temp.DropNodeFlag; } else if (temp.L < curDistance) { curDistance = temp.L; curRoad = temp.Edge; curPointTo = temp.Point_To; curDropNodeFlag = temp.DropNodeFlag; } } } } return(new DropOnEdge(curPointTo, result.Point_From, curDistance, curRoad, curDropNodeFlag)); }
protected abstract DropOnEdge CheckSquere(int a, int b, SquareMatrixBase squere_matrix, DropOnEdge result);
public DropOnEdge Find(IPoint xpoint, SquareMatrixBase squere_matrix) { //Определение квадрата входной точки int a = Convert.ToInt32(Math.Truncate((xpoint.X - squere_matrix.MinX) / squere_matrix.Delta)); int b = Convert.ToInt32(Math.Truncate((xpoint.Y - squere_matrix.MinY) / squere_matrix.Delta)); //если входная точка выходит за пределы квадрата, встраиваем её в крайний квадрат if (a < 0) { a = 0; } if (a >= squere_matrix.SizeX) { a = squere_matrix.SizeX - 1; } if (b < 0) { b = 0; } if (b >= squere_matrix.SizeY) { b = squere_matrix.SizeY - 1; } int old_a = a; int old_b = b; DropOnEdge result = new DropOnEdge(xpoint); var cheked_set = new HashSet <IndexSquere>(); result = CheckSquere(a, b, squere_matrix, result); cheked_set.Add(new IndexSquere(a, b)); //вычисление координат сторон квадрата double x1 = squere_matrix.MinX + a * squere_matrix.Delta; double x2 = squere_matrix.MinX + (a + 1) * squere_matrix.Delta; double y1 = squere_matrix.MinY + b * squere_matrix.Delta; double y2 = squere_matrix.MinY + (b + 1) * squere_matrix.Delta; //Если радиус поиска искомой точки выходит за пределы квадрата или точка не была найденна, выход на поиск вокруг квадрата if ((result.Point_To == null) || (Math.Abs(x1 - xpoint.X) < result.L) || (Math.Abs(x2 - xpoint.X) < result.L) || (Math.Abs(y1 - xpoint.Y) < result.L) || (Math.Abs(y2 - xpoint.Y) < result.L)) { //Условие выхода - 2 раза наличие значения искомой точки //Для случая выхода за пределы первого квадрата выходная переменная равна 1 и делается еще один лишний круг //Для случая не нахождения точки сразу double r = 0; do { r += squere_matrix.Delta; int check_from = Convert.ToInt32(Math.Truncate((xpoint.Y + r - squere_matrix.MinY) / squere_matrix.Delta)); int check_to = Convert.ToInt32(Math.Truncate((xpoint.Y - r - squere_matrix.MinY) / squere_matrix.Delta)) + 1; int current_b = check_from; Tuple <IPoint, IPoint> cross_circle; while (current_b > old_b) { //Выше центра круга cross_circle = fun_set.find_cross_line_and_circle(squere_matrix.MinY + squere_matrix.Delta * current_b, xpoint, r); if (cross_circle.Item1 != null && cross_circle.Item2 != null) { int from_a = Convert.ToInt32(Math.Truncate((cross_circle.Item1.X - squere_matrix.MinX) / squere_matrix.Delta)); int to_a = Convert.ToInt32(Math.Truncate((cross_circle.Item2.X - squere_matrix.MinX) / squere_matrix.Delta)); for (int j = from_a; j <= to_a; j++) { var temp_hash = new IndexSquere(j, current_b); if (!cheked_set.Contains(temp_hash)) { result = CheckSquere(j, current_b, squere_matrix, result); cheked_set.Add(temp_hash); } } } else if (cross_circle.Item1 != null) { int from_a = Convert.ToInt32(Math.Truncate((cross_circle.Item1.X - squere_matrix.MinX) / squere_matrix.Delta)); var temp_hash = new IndexSquere(from_a, current_b); if (!cheked_set.Contains(temp_hash)) { result = CheckSquere(from_a, current_b, squere_matrix, result); cheked_set.Add(temp_hash); } } current_b--; } //Обработка центра круга cross_circle = fun_set.find_cross_line_and_circle(xpoint.Y, xpoint, r); if (cross_circle.Item1 != null && cross_circle.Item2 != null) { int from_a = Convert.ToInt32(Math.Truncate((cross_circle.Item1.X - squere_matrix.MinX) / squere_matrix.Delta)); int to_a = Convert.ToInt32(Math.Truncate((cross_circle.Item2.X - squere_matrix.MinX) / squere_matrix.Delta)); for (int j = from_a; j <= to_a; j++) { var temp_hash = new IndexSquere(j, current_b); if (!cheked_set.Contains(temp_hash)) { result = CheckSquere(j, current_b, squere_matrix, result); cheked_set.Add(temp_hash); } } } while (current_b >= check_to) { //Ниже центра круга cross_circle = fun_set.find_cross_line_and_circle(squere_matrix.MinY + squere_matrix.Delta * current_b, xpoint, r); if (cross_circle.Item1 != null && cross_circle.Item2 != null) { int from_a = Convert.ToInt32(Math.Truncate((cross_circle.Item1.X - squere_matrix.MinX) / squere_matrix.Delta)); int to_a = Convert.ToInt32(Math.Truncate((cross_circle.Item2.X - squere_matrix.MinX) / squere_matrix.Delta)); for (int j = from_a; j <= to_a; j++) { var temp_hash = new IndexSquere(j, current_b - 1); if (!cheked_set.Contains(temp_hash)) { result = CheckSquere(j, current_b - 1, squere_matrix, result); cheked_set.Add(temp_hash); } } } else if (cross_circle.Item1 != null) { int from_a = Convert.ToInt32(Math.Truncate((cross_circle.Item1.X - squere_matrix.MinX) / squere_matrix.Delta)); var temp_hash = new IndexSquere(from_a, current_b - 1); if (!cheked_set.Contains(temp_hash)) { result = CheckSquere(from_a, current_b - 1, squere_matrix, result); cheked_set.Add(temp_hash); } } current_b--; } } while (result.Point_To == null || result.L > r); } return(result); }
protected override DropOnEdge CheckSquere(int a, int b, SquareMatrixBase square_matrix, DropOnEdge curr_result) { var s_matrix = square_matrix as SquareMatrixNodes; if (s_matrix == null) { throw new ArgumentException(nameof(square_matrix)); } if (a < 0 || a >= s_matrix.SizeX || b < 0 || b >= s_matrix.SizeY) { return(curr_result); } double curDistance = curr_result.L; IPoint curPoint = curr_result.Point_To; if (s_matrix.Matrix[a, b] != null) { foreach (var point in s_matrix.Matrix[a, b]) { double distance = fun_set.between_point(point, curr_result.Point_From); if (distance < curDistance) { curDistance = distance; curPoint = point; } } } return(new DropOnEdge(curPoint, curr_result.Point_From, curDistance)); }