From ba4e4b7703e522501556f899d4c65518fbd6c534 Mon Sep 17 00:00:00 2001 From: "Egli Adrian (IT-SCI-API-PFI)" <adrian.egli@sbb.ch> Date: Tue, 17 Sep 2019 12:12:52 +0200 Subject: [PATCH] refactored vec2 op --- .../Simple_Realistic_Railway_Generator.py | 22 +++---- flatland/core/grid/grid4_astar.py | 10 +-- flatland/core/grid/grid_utils.py | 61 +++++++++++++++---- 3 files changed, 65 insertions(+), 28 deletions(-) diff --git a/examples/Simple_Realistic_Railway_Generator.py b/examples/Simple_Realistic_Railway_Generator.py index 7f155cf2..4ffe6016 100644 --- a/examples/Simple_Realistic_Railway_Generator.py +++ b/examples/Simple_Realistic_Railway_Generator.py @@ -74,12 +74,12 @@ def realistic_rail_generator(num_cities=5, for i in range(len(generate_city_locations)): # station main orientation (horizontal or vertical rot_angle = np.random.choice(rotation_angles_set) - add_pos_val = Vec2d.scale_pos(Vec2d.rotate_pos((1, 0), rot_angle), + add_pos_val = Vec2d.scale(Vec2d.rotate((1, 0), rot_angle), int(max(1.0, (intern_city_size - 3) / 2))) - generate_city_locations[i][0] = Vec2d.add_pos(generate_city_locations[i][1], add_pos_val) - add_pos_val = Vec2d.scale_pos(Vec2d.rotate_pos((1, 0), 180 + rot_angle), + generate_city_locations[i][0] = Vec2d.add(generate_city_locations[i][1], add_pos_val) + add_pos_val = Vec2d.scale(Vec2d.rotate((1, 0), 180 + rot_angle), int(max(1.0, (intern_city_size - 3) / 2))) - generate_city_locations[i][1] = Vec2d.add_pos(generate_city_locations[i][1], add_pos_val) + generate_city_locations[i][1] = Vec2d.add(generate_city_locations[i][1], add_pos_val) return generate_city_locations def create_stations_from_city_locations(rail_trans: RailEnvTransitions, @@ -107,13 +107,13 @@ def realistic_rail_generator(num_cities=5, org_start_node = generate_city_locations[city_loop][0] org_end_node = generate_city_locations[city_loop][1] - ortho_trans = Vec2d.make_orthogonal_pos( - Vec2d.normalize_pos(Vec2d.subtract_pos(org_start_node, org_end_node))) + ortho_trans = Vec2d.make_orthogonal( + Vec2d.normalize(Vec2d.subtract(org_start_node, org_end_node))) s = (ct - number_of_connecting_tracks / 2.0) - start_node = Vec2d.ceil_pos( - Vec2d.add_pos(org_start_node, Vec2d.scale_pos(ortho_trans, s))) - end_node = Vec2d.ceil_pos( - Vec2d.add_pos(org_end_node, Vec2d.scale_pos(ortho_trans, s))) + start_node = Vec2d.ceil( + Vec2d.add(org_start_node, Vec2d.scale(ortho_trans, s))) + end_node = Vec2d.ceil( + Vec2d.add(org_end_node, Vec2d.scale(ortho_trans, s))) connection = connect_from_nodes(rail_trans, grid_map, start_node, end_node) if len(connection) > 0: @@ -248,7 +248,7 @@ def realistic_rail_generator(num_cities=5, continue ens = e_nodes[city_loop_find_shortest] for en in ens: - d = Vec2d.get_norm_pos(Vec2d.subtract_pos(en, start_node)) + d = Vec2d.get_euclidean_distance(start_node,en) if d < min_distance: min_distance = d end_node = en diff --git a/flatland/core/grid/grid4_astar.py b/flatland/core/grid/grid4_astar.py index 3b4e6938..5bec1ce4 100644 --- a/flatland/core/grid/grid4_astar.py +++ b/flatland/core/grid/grid4_astar.py @@ -1,6 +1,7 @@ from flatland.core.grid.grid4_utils import validate_new_transition from flatland.core.grid.grid_utils import IntVector2D from flatland.core.grid.grid_utils import IntVector2DArrayType +from flatland.core.grid.grid_utils import Vec2dOperations as Vec2d from flatland.core.grid.rail_env_grid import RailEnvTransitions from flatland.core.transition_map import GridTransitionMap @@ -29,8 +30,9 @@ class AStarNode: self.f = other.f -def a_star(rail_trans: RailEnvTransitions, grid_map: GridTransitionMap, start: IntVector2D, end: IntVector2D) -> \ - (IntVector2DArrayType): +def a_star(rail_trans: RailEnvTransitions, + grid_map: GridTransitionMap, + start: IntVector2D, end: IntVector2D) -> IntVector2DArrayType: """ Returns a list of tuples as a path from the given start to end. If no path is found, returns path to closest point to end. @@ -94,10 +96,8 @@ def a_star(rail_trans: RailEnvTransitions, grid_map: GridTransitionMap, start: I # create the f, g, and h values child.g = current_node.g + 1 - # this heuristic favors diagonal paths: - # child.h = ((child.pos[0] - end_node.pos[0]) ** 2) + ((child.pos[1] - end_node.pos[1]) ** 2) \# noqa: E800 # this heuristic avoids diagonal paths - child.h = abs(child.pos[0] - end_node.pos[0]) + abs(child.pos[1] - end_node.pos[1]) + child.h = Vec2d.get_manhattan_distance(child.pos, end_node.pos) child.f = child.g + child.h # already in the open list? diff --git a/flatland/core/grid/grid_utils.py b/flatland/core/grid/grid_utils.py index ffbf79a7..a9d6ffaa 100644 --- a/flatland/core/grid/grid_utils.py +++ b/flatland/core/grid/grid_utils.py @@ -11,7 +11,7 @@ IntVector2DArrayType = [] class Vec2dOperations: @staticmethod - def subtract_pos(node_a: Vector2D, node_b: Vector2D) -> Vector2D: + def subtract(node_a: Vector2D, node_b: Vector2D) -> Vector2D: """ vector operation : node_a - node_b @@ -24,7 +24,7 @@ class Vec2dOperations: return node_a[0] - node_b[0], node_a[1] - node_b[1] @staticmethod - def add_pos(node_a: Vector2D, node_b: Vector2D) -> Vector2D: + def add(node_a: Vector2D, node_b: Vector2D) -> Vector2D: """ vector operation : node_a + node_b @@ -37,7 +37,7 @@ class Vec2dOperations: return node_a[0] + node_b[0], node_a[1] + node_b[1] @staticmethod - def make_orthogonal_pos(node: Vector2D) -> Vector2D: + def make_orthogonal(node: Vector2D) -> Vector2D: """ vector operation : rotates the 2D vector +90° @@ -49,7 +49,7 @@ class Vec2dOperations: return node[1], -node[0] @staticmethod - def get_norm_pos(node: Vector2D) -> float: + def get_norm(node: Vector2D) -> float: """ calculates the euclidean norm of the 2d vector @@ -60,8 +60,45 @@ class Vec2dOperations: """ return np.sqrt(node[0] * node[0] + node[1] * node[1]) + + @staticmethod + def get_manhattan_norm(node: Vector2D) -> float: + """ + calculates the euclidean norm of the 2d vector + + :param node: tuple with coordinate (x,y) or 2d vector + :return: + ------- + returns the manhatten norm + """ + return abs(node[0] * node[0]) + abs(node[1] * node[1]) + + @staticmethod + def get_euclidean_distance(node_a: Vector2D,node_b: Vector2D) -> float: + """ + calculates the euclidean norm of the 2d vector + + :param node: tuple with coordinate (x,y) or 2d vector + :return: + ------- + returnss the manhatten distance + """ + return Vec2dOperations.get_norm(Vec2dOperations.subtract(node_b,node_a)) + + @staticmethod + def get_manhattan_distance(node_a: Vector2D, node_b: Vector2D) -> float: + """ + calculates the euclidean norm of the 2d vector + + :param node: tuple with coordinate (x,y) or 2d vector + :return: + ------- + returnss the manhatten distance + """ + return Vec2dOperations.get_manhattan_norm(Vec2dOperations.subtract(node_b, node_a)) + @staticmethod - def normalize_pos(node: Vector2D) -> Tuple[float, float]: + def normalize(node: Vector2D) -> Tuple[float, float]: """ normalize the 2d vector = v/|v| @@ -70,13 +107,13 @@ class Vec2dOperations: ------- tuple with coordinate (x,y) or 2d vector """ - n = Vec2dOperations.get_norm_pos(node) + n = Vec2dOperations.get_norm(node) if n > 0.0: n = 1 / n - return Vec2dOperations.scale_pos(node, n) + return Vec2dOperations.scale(node, n) @staticmethod - def scale_pos(node: Vector2D, scale: float) -> Vector2D: + def scale(node: Vector2D, scale: float) -> Vector2D: """ scales the 2d vector = node * scale @@ -89,7 +126,7 @@ class Vec2dOperations: return node[0] * scale, node[1] * scale @staticmethod - def round_pos(node: Vector2D) -> IntVector2D: + def round(node: Vector2D) -> IntVector2D: """ rounds the x and y coordinate and convert them to an integer values @@ -101,7 +138,7 @@ class Vec2dOperations: return int(np.round(node[0])), int(np.round(node[1])) @staticmethod - def ceil_pos(node: Vector2D) -> IntVector2D: + def ceil(node: Vector2D) -> IntVector2D: """ ceiling the x and y coordinate and convert them to an integer values @@ -113,7 +150,7 @@ class Vec2dOperations: return int(np.ceil(node[0])), int(np.ceil(node[1])) @staticmethod - def bound_pos(node: Vector2D, min_value: float, max_value: float) -> Vector2D: + def bound(node: Vector2D, min_value: float, max_value: float) -> Vector2D: """ force the values x and y to be between min_value and max_value @@ -127,7 +164,7 @@ class Vec2dOperations: return max(min_value, min(max_value, node[0])), max(min_value, min(max_value, node[1])) @staticmethod - def rotate_pos(node: Vector2D, rot_in_degree: float) -> Vector2D: + def rotate(node: Vector2D, rot_in_degree: float) -> Vector2D: """ rotate the 2d vector with given angle in degree -- GitLab