Advertisement
Guest User

Untitled

a guest
Oct 18th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.68 KB | None | 0 0
  1. import random
  2.  
  3. import matplotlib.pyplot as plt
  4. from shapely.geometry import Point, Polygon, LineString
  5. import math
  6.  
  7. from Model.CustomVertex import CustomVertex
  8. from SimulatedAnnealing import TravellingSalesmanProblem
  9. from Model.CustomLineString import CustomLinestring
  10.  
  11.  
  12. def generate_lines(area_vertex):
  13. for i in range(0, len(area_vertex) - 1, 1):
  14. initial_lines.append(LineString([area_vertex[i], area_vertex[i + 1]]))
  15.  
  16.  
  17. def angle(cx, cy, ex, ey):
  18. dy = ey - cy
  19. dx = ex - cx
  20. theta = math.atan2(dy, dx)
  21. theta *= 180 / math.pi
  22. return theta
  23.  
  24.  
  25. def generateOuterWalls(outerWallsCoordinatesList):
  26. outerWallsList = []
  27. for outerWall in outerWallsCoordinatesList:
  28. outerWallsList.append(LineString(outerWall))
  29. return outerWallsList
  30.  
  31.  
  32. def get_horizontal_and_vertical_walls_list(area_vertex):
  33. horizontalLineWallsList = []
  34. verticalLineWallsList = []
  35.  
  36. i = 0
  37. while i < len(area_vertex) - 1:
  38. lineAngle = angle(area_vertex[i][0], area_vertex[i][1], area_vertex[i + 1][0],
  39. area_vertex[i + 1][1])
  40.  
  41. if (1 < lineAngle <= 90) or (-180 <= lineAngle <= -90):
  42. verticalLineWallsList.append(LineString(
  43. [(area_vertex[i][0], area_vertex[i][1]), (area_vertex[i + 1][0], area_vertex[i + 1][1])]))
  44. else:
  45. horizontalLineWallsList.append(LineString(
  46. [(area_vertex[i][0], area_vertex[i][1]), (area_vertex[i + 1][0], area_vertex[i + 1][1])]))
  47. i += 1
  48.  
  49. return [horizontalLineWallsList, verticalLineWallsList]
  50.  
  51.  
  52. def vertical_parallel_offset(line_string, distance):
  53. x, y = line_string.xy
  54. x1 = x[0]
  55. x1 = x1 + distance
  56. y1 = y[0]
  57. x2 = x[1]
  58. x2 = x2 + distance
  59. y2 = y[1]
  60. return LineString([(x1, y1), (x2, y2)])
  61.  
  62.  
  63. def vertical_previous_parallel_offset(line_string, distance):
  64. x, y = line_string.xy
  65. x1 = x[0]
  66. x1 = x1 - distance
  67. y1 = y[0]
  68. x2 = x[1]
  69. x2 = x2 - distance
  70. y2 = y[1]
  71. return LineString([(x1, y1), (x2, y2)])
  72.  
  73.  
  74. def horizontal_parallel_offset(line_string, distance):
  75. x, y = line_string.xy
  76. x1 = x_min
  77. y1 = y[0]
  78. y1 = y1 + distance
  79. x2 = x_max
  80. y2 = y[1]
  81. y2 = y2 + distance
  82. return LineString([(x1, y1), (x2, y2)])
  83.  
  84.  
  85. def horizontal_previous_parallel_offset(line_string, distance):
  86. x, y = line_string.xy
  87. x1 = x_min
  88. y1 = y[0]
  89. y1 = y1 - distance
  90. x2 = x_max
  91. y2 = y[1]
  92. y2 = y2 - distance
  93. return LineString([(x1, y1), (x2, y2)])
  94.  
  95.  
  96. def calculateDistance(closest_wall, line, flag):
  97. if flag:
  98. x, y = line.xy
  99. if closest_wall.distance(line) < distanceOuterVertex:
  100. return outerWallDistance, True
  101.  
  102. return distanceInnerVertex, False
  103.  
  104.  
  105. def calculateVerticalNextDistance(closest_wall, line, flag):
  106. line = vertical_parallel_offset(line, 2)
  107.  
  108. if flag:
  109. x, y = line.xy
  110. if closest_wall.distance(line) < distanceOuterVertex:
  111. return outerWallDistance, True
  112.  
  113. return distanceInnerVertex, False
  114.  
  115.  
  116. def calculateVerticalPreviousDistance(closest_wall, line, flag):
  117. line = vertical_parallel_offset(line, -2)
  118.  
  119. if flag:
  120. x, y = line.xy
  121. if closest_wall.distance(line) < distanceOuterVertex:
  122. return outerWallDistance, True
  123.  
  124. return distanceInnerVertex, False
  125.  
  126.  
  127. def calculateHorizontalNextDistance(closest_wall, line, flag):
  128. line = horizontal_parallel_offset(line, 2)
  129.  
  130. if flag:
  131. x, y = line.xy
  132. if closest_wall.distance(line) < distanceOuterVertex:
  133. return outerWallDistance, True
  134.  
  135. return distanceInnerVertex, False
  136.  
  137.  
  138. def calculateHorizontalPreviousDistance(closest_wall, line, flag):
  139. line = horizontal_parallel_offset(line, -2)
  140.  
  141. if flag:
  142. x, y = line.xy
  143. if closest_wall.distance(line) < distanceOuterVertex:
  144. return outerWallDistance, True
  145.  
  146. return distanceInnerVertex, False
  147.  
  148.  
  149. def add_vertical_lines():
  150. first_vertical_line = verticalLineWalls[1]
  151. first_vertical_line_outer_flag = True if first_vertical_line in outerWalls else False
  152. first_vertical_line = vertical_parallel_offset(first_vertical_line, distanceWall)
  153.  
  154. second_vertical_line = verticalLineWalls[0]
  155. second_vertical_line_outer_flag = True if second_vertical_line in outerWalls else False
  156. second_vertical_line = vertical_parallel_offset(second_vertical_line, -distanceWall)
  157.  
  158. grid_lines_right = []
  159. grid_lines_right.append(CustomLinestring(first_vertical_line, first_vertical_line_outer_flag, None, None))
  160. grid_lines_left = []
  161. grid_lines_left.append(CustomLinestring(second_vertical_line, second_vertical_line_outer_flag, None, None))
  162.  
  163. while first_vertical_line.distance(second_vertical_line) > distanceInnerVertex * 2:
  164. distance, first_vertical_line_outer_flag = calculateDistance(verticalLineWalls[1], first_vertical_line,
  165. first_vertical_line_outer_flag)
  166. first_vertical_line = vertical_parallel_offset(first_vertical_line, distance)
  167. # first_prev_vertical_line = vertical_previous_parallel_offset(first_vertical_line, distance)
  168.  
  169. distance, second_vertical_line_outer_flag = calculateDistance(verticalLineWalls[0], second_vertical_line,
  170. second_vertical_line_outer_flag)
  171. second_vertical_line = vertical_parallel_offset(second_vertical_line, -distance)
  172. # second_prev_vertical_line = vertical_previous_parallel_offset(second_vertical_line, -distance)
  173.  
  174. grid_lines_right.append(
  175. CustomLinestring(first_vertical_line, first_vertical_line_outer_flag, None,
  176. None))
  177. grid_lines_left.append(
  178. CustomLinestring(second_vertical_line, second_vertical_line_outer_flag, None,
  179. None))
  180.  
  181. # first_vertical_line = first_next_vertical_line
  182. # second_vertical_line = second_next_vertical_line
  183.  
  184. last_ver_line_1 = grid_lines_right[len(grid_lines_right) - 1]
  185. last_ver_line_2 = grid_lines_left[len(grid_lines_left) - 1]
  186.  
  187. if last_ver_line_1.line_string.distance(last_ver_line_2.line_string) >= 2 * distanceInnerVertex:
  188. distance, first_vertical_line_outer_flag = calculateDistance(verticalLineWalls[1], last_ver_line_1.line_string,
  189. first_vertical_line_outer_flag)
  190. last_ver_line_1 = vertical_parallel_offset(last_ver_line_1, distance)
  191. last_ver_line_1 = grid_lines_right.append(
  192. CustomLinestring(last_ver_line_1, first_vertical_line_outer_flag, None,
  193. None))
  194.  
  195. for i in range(0, len(grid_lines_right)):
  196. if i == 0:
  197. line = grid_lines_right[i]
  198. line.next_line = grid_lines_right[i + 1].line_string
  199. grid_lines.append(line)
  200. elif i == len(grid_lines_right) - 1:
  201. line = grid_lines_right[i]
  202. line.previous_line = grid_lines_right[i - 1].line_string
  203. last_right = line
  204. else:
  205. line = grid_lines_right[i]
  206. line.previous_line = grid_lines_right[i - 1].line_string
  207. line.next_line = grid_lines_right[i + 1].line_string
  208. grid_lines.append(line)
  209.  
  210. for i in range(0, len(grid_lines_left)):
  211. if i == 0:
  212. line = grid_lines_left[i]
  213. line.next_line = grid_lines_left[i + 1].line_string
  214. grid_lines.append(line)
  215. elif i == len(grid_lines_left) - 1:
  216. line = grid_lines_left[i]
  217. line.previous_line = grid_lines_left[i - 1].line_string
  218. last_left = line
  219. else:
  220. line = grid_lines_left[i]
  221. line.previous_line = grid_lines_left[i - 1].line_string
  222. line.next_line = grid_lines_left[i + 1].line_string
  223. grid_lines.append(line)
  224.  
  225. last_right.next_line = last_left.line_string
  226. last_left.next_line = last_right.line_string
  227. grid_lines.append(last_left)
  228. grid_lines.append(last_right)
  229.  
  230.  
  231. def add_horizontal_lines():
  232. first_horizontal_line = horizontalLineWalls[0]
  233. first_horizontal_line_outer_flag = True if first_horizontal_line in outerWalls else False
  234. first_horizontal_line = horizontal_parallel_offset(first_horizontal_line, distanceWall)
  235.  
  236. second_horizontal_line = horizontalLineWalls[1]
  237. second_horizontal_line_outer_flag = True if second_horizontal_line in outerWalls else False
  238. second_horizontal_line = horizontal_parallel_offset(second_horizontal_line, -distanceWall)
  239.  
  240. grid_line_down = []
  241. grid_line_up = []
  242. grid_line_up.append(CustomLinestring(first_horizontal_line, first_horizontal_line_outer_flag, None, None))
  243. grid_line_down.append(CustomLinestring(second_horizontal_line, second_horizontal_line_outer_flag, None, None))
  244.  
  245. while first_horizontal_line.distance(second_horizontal_line) > distanceInnerVertex * 2:
  246. distance, first_horizontal_line_outer_flag = calculateDistance(horizontalLineWalls[0], first_horizontal_line,
  247. first_horizontal_line_outer_flag)
  248. first_horizontal_line = horizontal_parallel_offset(first_horizontal_line, distance)
  249. # first_prev_horizontal_line = horizontal_previous_parallel_offset(first_horizontal_line, distance)
  250.  
  251. distance, second_horizontal_line_outer_flag = calculateDistance(horizontalLineWalls[1], second_horizontal_line,
  252. second_horizontal_line_outer_flag)
  253. second_horizontal_line = horizontal_parallel_offset(second_horizontal_line, -distance)
  254. # second_prev_horizontal_line = horizontal_previous_parallel_offset(second_horizontal_line, -distance)
  255.  
  256. grid_line_up.append(
  257. CustomLinestring(first_horizontal_line, first_horizontal_line_outer_flag, None,
  258. None))
  259. # grid_lines.append(
  260. # CustomLinestring(first_horizontal_line, first_horizontal_line_outer_flag, first_prev_horizontal_line,
  261. # first_next_horizontal_line))
  262. grid_line_down.append(
  263. CustomLinestring(second_horizontal_line, second_horizontal_line_outer_flag, None,
  264. None))
  265. # grid_lines.append(
  266. # CustomLinestring(second_horizontal_line, second_horizontal_line_outer_flag, second_prev_horizontal_line,
  267. # second_next_horizontal_line))
  268.  
  269. # first_horizontal_line = first_next_horizontal_line
  270. # second_horizontal_line = second_next_horizontal_line
  271.  
  272. last_hor_line_1 = grid_line_up[len(grid_line_up) - 1]
  273. last_hor_line_2 = grid_line_down[len(grid_line_down) - 1]
  274. if last_hor_line_1.line_string.distance(last_hor_line_2.line_string) >= 2 * distanceInnerVertex:
  275. distance, first_horizontal_line_outer_flag = calculateDistance(horizontalLineWalls[0],
  276. last_hor_line_1.line_string,
  277. first_horizontal_line_outer_flag)
  278. last_hor_line_1 = horizontal_parallel_offset(last_hor_line_1, distance)
  279.  
  280. last_hor_line_1 = grid_line_up.append(
  281. CustomLinestring(last_hor_line_1, first_horizontal_line_outer_flag, None,
  282. None))
  283.  
  284. for i in range(0, len(grid_line_up)):
  285. if i == 0:
  286. line = grid_line_up[i]
  287. line.next_line = grid_line_up[i + 1].line_string
  288. grid_lines.append(line)
  289. elif i == len(grid_line_up) - 1:
  290. line = grid_line_up[i]
  291. line.previous_line = grid_line_up[i - 1].line_string
  292. last_up = line
  293. else:
  294. line = grid_line_up[i]
  295. line.previous_line = grid_line_up[i - 1].line_string
  296. line.next_line = grid_line_up[i + 1].line_string
  297. grid_lines.append(line)
  298.  
  299. for i in range(0, len(grid_line_down)):
  300. if i == 0:
  301. line = grid_line_down[i]
  302. line.next_line = grid_line_down[i + 1].line_string
  303. grid_lines.append(line)
  304. elif i == len(grid_line_up) - 1:
  305. line = grid_line_down[i]
  306. line.previous_line = grid_line_down[i - 1].line_string
  307. last_down = line
  308. else:
  309. line = grid_line_down[i]
  310. line.previous_line = grid_line_down[i - 1].line_string
  311. line.next_line = grid_line_down[i + 1].line_string
  312. grid_lines.append(line)
  313.  
  314. last_up.next_line = last_down.line_string
  315. last_down.next_line = last_up.line_string
  316. grid_lines.append(last_up)
  317. grid_lines.append(last_down)
  318.  
  319.  
  320. def get_neighbours(line1, line2, area):
  321. neighbours = []
  322.  
  323. if line1.previous_line is not None:
  324. point = line1.previous_line.intersection(line2.line_string)
  325. if line1.previous_line.intersects(line2.line_string) and area.contains(point):
  326. neighbours.append(point)
  327.  
  328. if line1.next_line is not None:
  329. point = line1.next_line.intersection(line2.line_string)
  330. if line1.next_line.intersects(line2.line_string) and area.contains(point):
  331. neighbours.append(point)
  332.  
  333. if line2.previous_line is not None:
  334. point = line2.previous_line.intersection(line1.line_string)
  335. if line2.previous_line.intersects(line1.line_string) and area.contains(point):
  336. neighbours.append(point)
  337.  
  338. if line2.next_line is not None:
  339. point = line2.next_line.intersection(line1.line_string)
  340. if line2.next_line.intersects(line1.line_string) and area.contains(point):
  341. neighbours.append(point)
  342.  
  343. return neighbours
  344.  
  345.  
  346. def find_nearest_point_from_grid(starting_point, grid_points, outer_walls):
  347. if len(outer_walls) > 0:
  348. min = float('inf')
  349. min_vertex = None
  350. for grid_point in grid_points:
  351. if grid_point.outer_vertex == 0:
  352. distance = grid_point.point.distance(starting_point)
  353. if distance < min:
  354. min = distance
  355. min_vertex = grid_point
  356. return min_vertex
  357. else:
  358. min = math.inf
  359. min_vertex = None
  360. for grid_point in grid_points:
  361. distance = grid_point.point.distance(starting_point)
  362. if distance < min:
  363. min = distance
  364. min_vertex = grid_point
  365. return min_vertex
  366.  
  367.  
  368. def map_points_to_custom_vertexes(points, grid_points):
  369. for i in range(0, len(points)):
  370. element_index = grid_points.index(CustomVertex(points[i], 0, None))
  371. point = grid_points[element_index]
  372. points[i] = point
  373.  
  374.  
  375. def remove_edges(edges_elapsed_path, point):
  376. for edge in edges_elapsed_path:
  377. p = edge.split("->")
  378. if str(point) in p[0]:
  379. edges_elapsed_path.remove(edge)
  380.  
  381. def generate_path(grid_points, starting_point, outer_walls):
  382. points_path = [CustomVertex(starting_point, 0, None)]
  383. edges_elapsed_path = []
  384.  
  385. point = find_nearest_point_from_grid(starting_point, grid_points, outer_walls)
  386.  
  387. points_path.append(point)
  388.  
  389. while True:
  390.  
  391. # print("points path" + str(len(points_path)) + " " + "grid points" + str(len(grid_points)))
  392.  
  393. if len(points_path) >147:
  394. print("asd")
  395.  
  396. if len(points_path) == len(grid_points) + 1:
  397. break
  398.  
  399. neighbours = point.neighbours
  400.  
  401. if point.outer_vertex == 0:
  402. outer_vertexes = list(
  403. filter(
  404. lambda p: p.outer_vertex == 0
  405. and p not in points_path
  406. and str(point) + "->" + str(p) not in edges_elapsed_path
  407. , neighbours
  408. )
  409. )
  410.  
  411. if len(outer_vertexes) > 0:
  412. max = point.point.distance(outer_vertexes[0].point)
  413. max_element = outer_vertexes[0]
  414. for outer_vertex in outer_vertexes:
  415. if point.point.distance(outer_vertex.point) > max:
  416. max = point.point.distance(outer_vertex.point)
  417. max_element = outer_vertex
  418. points_path.append(max_element)
  419. edges_elapsed_path.append(str(point) + "->" + str(max_element))
  420. point = max_element
  421.  
  422. else:
  423. neighbours = list(
  424. filter(
  425. lambda p: p not in points_path
  426. and str(point) + "->" + str(p) not in edges_elapsed_path
  427. , neighbours
  428. )
  429. )
  430. if len(neighbours) > 0:
  431. max = point.point.distance(neighbours[0].point)
  432. max_element = neighbours[0]
  433. for neighbour in neighbours:
  434. if point.point.distance(neighbour.point) > max:
  435. max = point.point.distance(neighbour.point)
  436. max_element = neighbour
  437. points_path.append(max_element)
  438. edges_elapsed_path.append(str(point) + "->" + str(max_element))
  439. point = max_element
  440.  
  441. else:
  442. points_path = points_path[:-1]
  443. remove_edges(edges_elapsed_path,point)
  444. point = points_path[-1]
  445.  
  446. else:
  447. neighbours = list(
  448. filter(
  449. lambda p: p not in points_path
  450. and str(point) + "->" + str(p) not in edges_elapsed_path
  451. , neighbours
  452. )
  453. )
  454. if len(neighbours) > 0:
  455. max = point.point.distance(neighbours[0].point)
  456. max_element = neighbours[0]
  457. for neighbour in neighbours:
  458. if point.point.distance(neighbour.point) > max:
  459. max = point.point.distance(neighbour.point)
  460. max_element = neighbour
  461. points_path.append(max_element)
  462. edges_elapsed_path.append(str(point) + "->" + str(max_element))
  463. point = max_element
  464. else:
  465. points_path = points_path[:-1]
  466. remove_edges(edges_elapsed_path, point)
  467. point = points_path[-1]
  468.  
  469. for i in range(0, len(points_path)):
  470. drawp = points_path[i].point.xy
  471. plt.scatter(drawp[0], drawp[1])
  472. if i + 1 < len(points_path):
  473. drawp = points_path[i].point
  474. drawp1 = points_path[i + 1].point
  475. line = LineString([drawp, drawp1])
  476. x, y = line.xy
  477. plt.plot(x, y)
  478.  
  479. x, y = area.exterior.xy
  480. plt.plot(x, y)
  481.  
  482. plt.show()
  483.  
  484. return points_path
  485.  
  486.  
  487. if __name__ == "__main__":
  488. area_vertex = [(0, 0), (50, 0), (50, 40), (0, 40), (0, 0)]
  489. outerWallsCoordinatesList = [[(0, 0), (50, 0)], [(0, 40), (0, 0)]]
  490.  
  491. initial_lines = []
  492. grid_lines = []
  493. all_parallel_lines = []
  494. grid_points = []
  495.  
  496. startingPoint = (1, 0) # not needed at the time
  497. distanceOuterVertex = 8 # 2 from starting of the wall and then 3 lines on 2 length
  498. distanceInnerVertex = 4
  499. outerWallDistance = distanceWall = 2
  500.  
  501. x_min = min(p[0] for p in area_vertex)
  502. x_max = max(p[0] for p in area_vertex)
  503. y_min = min(p[1] for p in area_vertex)
  504. y_max = max(p[1] for p in area_vertex)
  505.  
  506. outerWalls = generateOuterWalls(outerWallsCoordinatesList)
  507. generate_lines(area_vertex)
  508.  
  509. horizontalLineWalls, verticalLineWalls = get_horizontal_and_vertical_walls_list(area_vertex)
  510.  
  511. add_vertical_lines()
  512. add_horizontal_lines()
  513.  
  514. fig, ax = plt.subplots()
  515. ax.set_xlim(-10, x_max + 2)
  516. ax.set_ylim(-10, y_max + 2)
  517.  
  518. area = Polygon(area_vertex)
  519.  
  520. for i in range(0, len(grid_lines)):
  521. for j in range(i + 1, len(grid_lines)):
  522. if grid_lines[i].line_string.intersects(grid_lines[j].line_string):
  523. intersectionPoint = grid_lines[i].line_string.intersection(grid_lines[j].line_string)
  524. outer_flag = grid_lines[i].outer_vertex_flag or grid_lines[j].outer_vertex_flag
  525. if area.contains(intersectionPoint):
  526. neighbours_list = get_neighbours(grid_lines[i], grid_lines[j], area)
  527. grid_points.append(CustomVertex(intersectionPoint, outer_flag, neighbours_list))
  528.  
  529. for grid_point in grid_points:
  530. map_points_to_custom_vertexes(grid_point.neighbours, grid_points)
  531.  
  532. path = generate_path(grid_points, Point(startingPoint), outerWalls)
  533.  
  534. for i in range(0, len(path)):
  535. point = path[i].point.xy
  536. plt.scatter(point[0], point[1])
  537. if i + 1 < len(path):
  538. point = path[i].point
  539. point1 = path[i + 1].point
  540. line = LineString([point, point1])
  541. x, y = line.xy
  542. plt.plot(x, y)
  543.  
  544. x, y = area.exterior.xy
  545. plt.plot(x, y)
  546.  
  547. plt.show()
  548.  
  549. # for i in range(0, len(grid_points)):
  550. # point = grid_points[i].point.xy
  551. # plt.scatter(point[0], point[1])
  552. # point = grid_points[i]
  553. # for j in range(0, len(point.neighbours)):
  554. # line = LineString([(point.point), point.neighbours[j].point])
  555. # x, y = line.xy
  556. # plt.plot(x, y)
  557. #
  558. # for i in range(0, len(grid_lines)):
  559. # x, y = grid_lines[i].line_string.xy
  560. # plt.plot(x, y)
  561. #
  562. # x, y = area.exterior.xy
  563. # plt.plot(x, y)
  564. #
  565. # plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement