Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import random
- import matplotlib.pyplot as plt
- from shapely.geometry import Point, Polygon, LineString
- import math
- from Model.CustomVertex import CustomVertex
- from SimulatedAnnealing import TravellingSalesmanProblem
- from Model.CustomLineString import CustomLinestring
- def generate_lines(area_vertex):
- for i in range(0, len(area_vertex) - 1, 1):
- initial_lines.append(LineString([area_vertex[i], area_vertex[i + 1]]))
- def angle(cx, cy, ex, ey):
- dy = ey - cy
- dx = ex - cx
- theta = math.atan2(dy, dx)
- theta *= 180 / math.pi
- return theta
- def generateOuterWalls(outerWallsCoordinatesList):
- outerWallsList = []
- for outerWall in outerWallsCoordinatesList:
- outerWallsList.append(LineString(outerWall))
- return outerWallsList
- def get_horizontal_and_vertical_walls_list(area_vertex):
- horizontalLineWallsList = []
- verticalLineWallsList = []
- i = 0
- while i < len(area_vertex) - 1:
- lineAngle = angle(area_vertex[i][0], area_vertex[i][1], area_vertex[i + 1][0],
- area_vertex[i + 1][1])
- if (1 < lineAngle <= 90) or (-180 <= lineAngle <= -90):
- verticalLineWallsList.append(LineString(
- [(area_vertex[i][0], area_vertex[i][1]), (area_vertex[i + 1][0], area_vertex[i + 1][1])]))
- else:
- horizontalLineWallsList.append(LineString(
- [(area_vertex[i][0], area_vertex[i][1]), (area_vertex[i + 1][0], area_vertex[i + 1][1])]))
- i += 1
- return [horizontalLineWallsList, verticalLineWallsList]
- def vertical_parallel_offset(line_string, distance):
- x, y = line_string.xy
- x1 = x[0]
- x1 = x1 + distance
- y1 = y[0]
- x2 = x[1]
- x2 = x2 + distance
- y2 = y[1]
- return LineString([(x1, y1), (x2, y2)])
- def vertical_previous_parallel_offset(line_string, distance):
- x, y = line_string.xy
- x1 = x[0]
- x1 = x1 - distance
- y1 = y[0]
- x2 = x[1]
- x2 = x2 - distance
- y2 = y[1]
- return LineString([(x1, y1), (x2, y2)])
- def horizontal_parallel_offset(line_string, distance):
- x, y = line_string.xy
- x1 = x_min
- y1 = y[0]
- y1 = y1 + distance
- x2 = x_max
- y2 = y[1]
- y2 = y2 + distance
- return LineString([(x1, y1), (x2, y2)])
- def horizontal_previous_parallel_offset(line_string, distance):
- x, y = line_string.xy
- x1 = x_min
- y1 = y[0]
- y1 = y1 - distance
- x2 = x_max
- y2 = y[1]
- y2 = y2 - distance
- return LineString([(x1, y1), (x2, y2)])
- def calculateDistance(closest_wall, line, flag):
- if flag:
- x, y = line.xy
- if closest_wall.distance(line) < distanceOuterVertex:
- return outerWallDistance, True
- return distanceInnerVertex, False
- def calculateVerticalNextDistance(closest_wall, line, flag):
- line = vertical_parallel_offset(line, 2)
- if flag:
- x, y = line.xy
- if closest_wall.distance(line) < distanceOuterVertex:
- return outerWallDistance, True
- return distanceInnerVertex, False
- def calculateVerticalPreviousDistance(closest_wall, line, flag):
- line = vertical_parallel_offset(line, -2)
- if flag:
- x, y = line.xy
- if closest_wall.distance(line) < distanceOuterVertex:
- return outerWallDistance, True
- return distanceInnerVertex, False
- def calculateHorizontalNextDistance(closest_wall, line, flag):
- line = horizontal_parallel_offset(line, 2)
- if flag:
- x, y = line.xy
- if closest_wall.distance(line) < distanceOuterVertex:
- return outerWallDistance, True
- return distanceInnerVertex, False
- def calculateHorizontalPreviousDistance(closest_wall, line, flag):
- line = horizontal_parallel_offset(line, -2)
- if flag:
- x, y = line.xy
- if closest_wall.distance(line) < distanceOuterVertex:
- return outerWallDistance, True
- return distanceInnerVertex, False
- def add_vertical_lines():
- first_vertical_line = verticalLineWalls[1]
- first_vertical_line_outer_flag = True if first_vertical_line in outerWalls else False
- first_vertical_line = vertical_parallel_offset(first_vertical_line, distanceWall)
- second_vertical_line = verticalLineWalls[0]
- second_vertical_line_outer_flag = True if second_vertical_line in outerWalls else False
- second_vertical_line = vertical_parallel_offset(second_vertical_line, -distanceWall)
- grid_lines_right = []
- grid_lines_right.append(CustomLinestring(first_vertical_line, first_vertical_line_outer_flag, None, None))
- grid_lines_left = []
- grid_lines_left.append(CustomLinestring(second_vertical_line, second_vertical_line_outer_flag, None, None))
- while first_vertical_line.distance(second_vertical_line) > distanceInnerVertex * 2:
- distance, first_vertical_line_outer_flag = calculateDistance(verticalLineWalls[1], first_vertical_line,
- first_vertical_line_outer_flag)
- first_vertical_line = vertical_parallel_offset(first_vertical_line, distance)
- # first_prev_vertical_line = vertical_previous_parallel_offset(first_vertical_line, distance)
- distance, second_vertical_line_outer_flag = calculateDistance(verticalLineWalls[0], second_vertical_line,
- second_vertical_line_outer_flag)
- second_vertical_line = vertical_parallel_offset(second_vertical_line, -distance)
- # second_prev_vertical_line = vertical_previous_parallel_offset(second_vertical_line, -distance)
- grid_lines_right.append(
- CustomLinestring(first_vertical_line, first_vertical_line_outer_flag, None,
- None))
- grid_lines_left.append(
- CustomLinestring(second_vertical_line, second_vertical_line_outer_flag, None,
- None))
- # first_vertical_line = first_next_vertical_line
- # second_vertical_line = second_next_vertical_line
- last_ver_line_1 = grid_lines_right[len(grid_lines_right) - 1]
- last_ver_line_2 = grid_lines_left[len(grid_lines_left) - 1]
- if last_ver_line_1.line_string.distance(last_ver_line_2.line_string) >= 2 * distanceInnerVertex:
- distance, first_vertical_line_outer_flag = calculateDistance(verticalLineWalls[1], last_ver_line_1.line_string,
- first_vertical_line_outer_flag)
- last_ver_line_1 = vertical_parallel_offset(last_ver_line_1, distance)
- last_ver_line_1 = grid_lines_right.append(
- CustomLinestring(last_ver_line_1, first_vertical_line_outer_flag, None,
- None))
- for i in range(0, len(grid_lines_right)):
- if i == 0:
- line = grid_lines_right[i]
- line.next_line = grid_lines_right[i + 1].line_string
- grid_lines.append(line)
- elif i == len(grid_lines_right) - 1:
- line = grid_lines_right[i]
- line.previous_line = grid_lines_right[i - 1].line_string
- last_right = line
- else:
- line = grid_lines_right[i]
- line.previous_line = grid_lines_right[i - 1].line_string
- line.next_line = grid_lines_right[i + 1].line_string
- grid_lines.append(line)
- for i in range(0, len(grid_lines_left)):
- if i == 0:
- line = grid_lines_left[i]
- line.next_line = grid_lines_left[i + 1].line_string
- grid_lines.append(line)
- elif i == len(grid_lines_left) - 1:
- line = grid_lines_left[i]
- line.previous_line = grid_lines_left[i - 1].line_string
- last_left = line
- else:
- line = grid_lines_left[i]
- line.previous_line = grid_lines_left[i - 1].line_string
- line.next_line = grid_lines_left[i + 1].line_string
- grid_lines.append(line)
- last_right.next_line = last_left.line_string
- last_left.next_line = last_right.line_string
- grid_lines.append(last_left)
- grid_lines.append(last_right)
- def add_horizontal_lines():
- first_horizontal_line = horizontalLineWalls[0]
- first_horizontal_line_outer_flag = True if first_horizontal_line in outerWalls else False
- first_horizontal_line = horizontal_parallel_offset(first_horizontal_line, distanceWall)
- second_horizontal_line = horizontalLineWalls[1]
- second_horizontal_line_outer_flag = True if second_horizontal_line in outerWalls else False
- second_horizontal_line = horizontal_parallel_offset(second_horizontal_line, -distanceWall)
- grid_line_down = []
- grid_line_up = []
- grid_line_up.append(CustomLinestring(first_horizontal_line, first_horizontal_line_outer_flag, None, None))
- grid_line_down.append(CustomLinestring(second_horizontal_line, second_horizontal_line_outer_flag, None, None))
- while first_horizontal_line.distance(second_horizontal_line) > distanceInnerVertex * 2:
- distance, first_horizontal_line_outer_flag = calculateDistance(horizontalLineWalls[0], first_horizontal_line,
- first_horizontal_line_outer_flag)
- first_horizontal_line = horizontal_parallel_offset(first_horizontal_line, distance)
- # first_prev_horizontal_line = horizontal_previous_parallel_offset(first_horizontal_line, distance)
- distance, second_horizontal_line_outer_flag = calculateDistance(horizontalLineWalls[1], second_horizontal_line,
- second_horizontal_line_outer_flag)
- second_horizontal_line = horizontal_parallel_offset(second_horizontal_line, -distance)
- # second_prev_horizontal_line = horizontal_previous_parallel_offset(second_horizontal_line, -distance)
- grid_line_up.append(
- CustomLinestring(first_horizontal_line, first_horizontal_line_outer_flag, None,
- None))
- # grid_lines.append(
- # CustomLinestring(first_horizontal_line, first_horizontal_line_outer_flag, first_prev_horizontal_line,
- # first_next_horizontal_line))
- grid_line_down.append(
- CustomLinestring(second_horizontal_line, second_horizontal_line_outer_flag, None,
- None))
- # grid_lines.append(
- # CustomLinestring(second_horizontal_line, second_horizontal_line_outer_flag, second_prev_horizontal_line,
- # second_next_horizontal_line))
- # first_horizontal_line = first_next_horizontal_line
- # second_horizontal_line = second_next_horizontal_line
- last_hor_line_1 = grid_line_up[len(grid_line_up) - 1]
- last_hor_line_2 = grid_line_down[len(grid_line_down) - 1]
- if last_hor_line_1.line_string.distance(last_hor_line_2.line_string) >= 2 * distanceInnerVertex:
- distance, first_horizontal_line_outer_flag = calculateDistance(horizontalLineWalls[0],
- last_hor_line_1.line_string,
- first_horizontal_line_outer_flag)
- last_hor_line_1 = horizontal_parallel_offset(last_hor_line_1, distance)
- last_hor_line_1 = grid_line_up.append(
- CustomLinestring(last_hor_line_1, first_horizontal_line_outer_flag, None,
- None))
- for i in range(0, len(grid_line_up)):
- if i == 0:
- line = grid_line_up[i]
- line.next_line = grid_line_up[i + 1].line_string
- grid_lines.append(line)
- elif i == len(grid_line_up) - 1:
- line = grid_line_up[i]
- line.previous_line = grid_line_up[i - 1].line_string
- last_up = line
- else:
- line = grid_line_up[i]
- line.previous_line = grid_line_up[i - 1].line_string
- line.next_line = grid_line_up[i + 1].line_string
- grid_lines.append(line)
- for i in range(0, len(grid_line_down)):
- if i == 0:
- line = grid_line_down[i]
- line.next_line = grid_line_down[i + 1].line_string
- grid_lines.append(line)
- elif i == len(grid_line_up) - 1:
- line = grid_line_down[i]
- line.previous_line = grid_line_down[i - 1].line_string
- last_down = line
- else:
- line = grid_line_down[i]
- line.previous_line = grid_line_down[i - 1].line_string
- line.next_line = grid_line_down[i + 1].line_string
- grid_lines.append(line)
- last_up.next_line = last_down.line_string
- last_down.next_line = last_up.line_string
- grid_lines.append(last_up)
- grid_lines.append(last_down)
- def get_neighbours(line1, line2, area):
- neighbours = []
- if line1.previous_line is not None:
- point = line1.previous_line.intersection(line2.line_string)
- if line1.previous_line.intersects(line2.line_string) and area.contains(point):
- neighbours.append(point)
- if line1.next_line is not None:
- point = line1.next_line.intersection(line2.line_string)
- if line1.next_line.intersects(line2.line_string) and area.contains(point):
- neighbours.append(point)
- if line2.previous_line is not None:
- point = line2.previous_line.intersection(line1.line_string)
- if line2.previous_line.intersects(line1.line_string) and area.contains(point):
- neighbours.append(point)
- if line2.next_line is not None:
- point = line2.next_line.intersection(line1.line_string)
- if line2.next_line.intersects(line1.line_string) and area.contains(point):
- neighbours.append(point)
- return neighbours
- def find_nearest_point_from_grid(starting_point, grid_points, outer_walls):
- if len(outer_walls) > 0:
- min = float('inf')
- min_vertex = None
- for grid_point in grid_points:
- if grid_point.outer_vertex == 0:
- distance = grid_point.point.distance(starting_point)
- if distance < min:
- min = distance
- min_vertex = grid_point
- return min_vertex
- else:
- min = math.inf
- min_vertex = None
- for grid_point in grid_points:
- distance = grid_point.point.distance(starting_point)
- if distance < min:
- min = distance
- min_vertex = grid_point
- return min_vertex
- def map_points_to_custom_vertexes(points, grid_points):
- for i in range(0, len(points)):
- element_index = grid_points.index(CustomVertex(points[i], 0, None))
- point = grid_points[element_index]
- points[i] = point
- def remove_edges(edges_elapsed_path, point):
- for edge in edges_elapsed_path:
- p = edge.split("->")
- if str(point) in p[0]:
- edges_elapsed_path.remove(edge)
- def generate_path(grid_points, starting_point, outer_walls):
- points_path = [CustomVertex(starting_point, 0, None)]
- edges_elapsed_path = []
- point = find_nearest_point_from_grid(starting_point, grid_points, outer_walls)
- points_path.append(point)
- while True:
- # print("points path" + str(len(points_path)) + " " + "grid points" + str(len(grid_points)))
- if len(points_path) >147:
- print("asd")
- if len(points_path) == len(grid_points) + 1:
- break
- neighbours = point.neighbours
- if point.outer_vertex == 0:
- outer_vertexes = list(
- filter(
- lambda p: p.outer_vertex == 0
- and p not in points_path
- and str(point) + "->" + str(p) not in edges_elapsed_path
- , neighbours
- )
- )
- if len(outer_vertexes) > 0:
- max = point.point.distance(outer_vertexes[0].point)
- max_element = outer_vertexes[0]
- for outer_vertex in outer_vertexes:
- if point.point.distance(outer_vertex.point) > max:
- max = point.point.distance(outer_vertex.point)
- max_element = outer_vertex
- points_path.append(max_element)
- edges_elapsed_path.append(str(point) + "->" + str(max_element))
- point = max_element
- else:
- neighbours = list(
- filter(
- lambda p: p not in points_path
- and str(point) + "->" + str(p) not in edges_elapsed_path
- , neighbours
- )
- )
- if len(neighbours) > 0:
- max = point.point.distance(neighbours[0].point)
- max_element = neighbours[0]
- for neighbour in neighbours:
- if point.point.distance(neighbour.point) > max:
- max = point.point.distance(neighbour.point)
- max_element = neighbour
- points_path.append(max_element)
- edges_elapsed_path.append(str(point) + "->" + str(max_element))
- point = max_element
- else:
- points_path = points_path[:-1]
- remove_edges(edges_elapsed_path,point)
- point = points_path[-1]
- else:
- neighbours = list(
- filter(
- lambda p: p not in points_path
- and str(point) + "->" + str(p) not in edges_elapsed_path
- , neighbours
- )
- )
- if len(neighbours) > 0:
- max = point.point.distance(neighbours[0].point)
- max_element = neighbours[0]
- for neighbour in neighbours:
- if point.point.distance(neighbour.point) > max:
- max = point.point.distance(neighbour.point)
- max_element = neighbour
- points_path.append(max_element)
- edges_elapsed_path.append(str(point) + "->" + str(max_element))
- point = max_element
- else:
- points_path = points_path[:-1]
- remove_edges(edges_elapsed_path, point)
- point = points_path[-1]
- for i in range(0, len(points_path)):
- drawp = points_path[i].point.xy
- plt.scatter(drawp[0], drawp[1])
- if i + 1 < len(points_path):
- drawp = points_path[i].point
- drawp1 = points_path[i + 1].point
- line = LineString([drawp, drawp1])
- x, y = line.xy
- plt.plot(x, y)
- x, y = area.exterior.xy
- plt.plot(x, y)
- plt.show()
- return points_path
- if __name__ == "__main__":
- area_vertex = [(0, 0), (50, 0), (50, 40), (0, 40), (0, 0)]
- outerWallsCoordinatesList = [[(0, 0), (50, 0)], [(0, 40), (0, 0)]]
- initial_lines = []
- grid_lines = []
- all_parallel_lines = []
- grid_points = []
- startingPoint = (1, 0) # not needed at the time
- distanceOuterVertex = 8 # 2 from starting of the wall and then 3 lines on 2 length
- distanceInnerVertex = 4
- outerWallDistance = distanceWall = 2
- x_min = min(p[0] for p in area_vertex)
- x_max = max(p[0] for p in area_vertex)
- y_min = min(p[1] for p in area_vertex)
- y_max = max(p[1] for p in area_vertex)
- outerWalls = generateOuterWalls(outerWallsCoordinatesList)
- generate_lines(area_vertex)
- horizontalLineWalls, verticalLineWalls = get_horizontal_and_vertical_walls_list(area_vertex)
- add_vertical_lines()
- add_horizontal_lines()
- fig, ax = plt.subplots()
- ax.set_xlim(-10, x_max + 2)
- ax.set_ylim(-10, y_max + 2)
- area = Polygon(area_vertex)
- for i in range(0, len(grid_lines)):
- for j in range(i + 1, len(grid_lines)):
- if grid_lines[i].line_string.intersects(grid_lines[j].line_string):
- intersectionPoint = grid_lines[i].line_string.intersection(grid_lines[j].line_string)
- outer_flag = grid_lines[i].outer_vertex_flag or grid_lines[j].outer_vertex_flag
- if area.contains(intersectionPoint):
- neighbours_list = get_neighbours(grid_lines[i], grid_lines[j], area)
- grid_points.append(CustomVertex(intersectionPoint, outer_flag, neighbours_list))
- for grid_point in grid_points:
- map_points_to_custom_vertexes(grid_point.neighbours, grid_points)
- path = generate_path(grid_points, Point(startingPoint), outerWalls)
- for i in range(0, len(path)):
- point = path[i].point.xy
- plt.scatter(point[0], point[1])
- if i + 1 < len(path):
- point = path[i].point
- point1 = path[i + 1].point
- line = LineString([point, point1])
- x, y = line.xy
- plt.plot(x, y)
- x, y = area.exterior.xy
- plt.plot(x, y)
- plt.show()
- # for i in range(0, len(grid_points)):
- # point = grid_points[i].point.xy
- # plt.scatter(point[0], point[1])
- # point = grid_points[i]
- # for j in range(0, len(point.neighbours)):
- # line = LineString([(point.point), point.neighbours[j].point])
- # x, y = line.xy
- # plt.plot(x, y)
- #
- # for i in range(0, len(grid_lines)):
- # x, y = grid_lines[i].line_string.xy
- # plt.plot(x, y)
- #
- # x, y = area.exterior.xy
- # plt.plot(x, y)
- #
- # plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement