reachable = np.zeros((m, n)) reachable[0, 0] = free_space[0, 0] for i in range(1, m): reachable[i, 0] = reachable[i-1, 0] and free_space[i, 0] for j in range(1, n): reachable[0, j] = reachable[0, j-1] and free_space[0, j] for i in range(1, m): for j in range(1, n): reachable[i, j] = free_space[i, j] and (reachable[i-1, j] or reachable[i, j-1] or reachable[i-1, j-1]) return reachable
= np.zeros((m, n)) reachable[0, 0] = free_space[0, 0] for i in range(1, m): reachable[i, 0] = reachable[i-1, 0] and free_space[i, 0] for j in range(1, n): reachable[0, j] = reachable[0, j-1] and free_space[0, j] for i in range(1, m): for j in range(1, n): reachable[i, j] = free_space[i, j] and (reachable[i-1, j] or reachable[i, j-1] or reachable[i-1, j-1]) return reachable アルゴリズムの詳細 単調増加するパスが描けるかを判定
= reachable.shape if not reachable[-1, -1]: return None path = [(m-1, n-1)] i, j = m-1, n-1 while i > 0 or j > 0: if i > 0 and reachable[i-1, j]: i -= 1 elif j > 0 and reachable[i, j-1]: j -= 1 else: i -= 1 j -= 1 path.append((i, j)) return path[::-1]
追加する def find_monotone_path(reachable): m, n = reachable.shape if not reachable[-1, -1]: return None path = [(m-1, n-1)] i, j = m-1, n-1 while i > 0 or j > 0: if i > 0 and reachable[i-1, j]: i -= 1 elif j > 0 and reachable[i, j-1]: j -= 1 else: i -= 1 j -= 1 path.append((i, j)) return path[::-1]
if epsilon_max is None: epsilon_max = max( max(euclidean_distance(p1, p2) for p1 in curve1 for p2 in curve2), max(point_to_segment_distance(p, curve1[i], curve1[i+1]) for i in range(len(curve1)-1) for p in curve2), max(point_to_segment_distance(p, curve2[i], curve2[i+1]) for i in range(len(curve2)-1) for p in curve1) ) final_path = None while epsilon_max - epsilon_min > tolerance: epsilon = (epsilon_min + epsilon_max) / 2 free_space = calculate_free_space(curve1, curve2, epsilon) reachable = calculate_reachable_space(free_space) path = find_monotone_path(reachable) if path is not None: epsilon_max = epsilon final_path = path else: epsilon_min = epsilon return epsilon_max, final_path
• pathが存在しない ◦ これ以下には存在しない ◦ epsilonの最大値を小さくする 二分探索でフレシェ距離を計算する def calculate_frechet_distance(curve1, curve2, epsilon_min=0, epsilon_max=None, tolerance=1e-6): if epsilon_max is None: epsilon_max = max( max(euclidean_distance(p1, p2) for p1 in curve1 for p2 in curve2), max(point_to_segment_distance(p, curve1[i], curve1[i+1]) for i in range(len(curve1)-1) for p in curve2), max(point_to_segment_distance(p, curve2[i], curve2[i+1]) for i in range(len(curve2)-1) for p in curve1) ) final_path = None while epsilon_max - epsilon_min > tolerance: epsilon = (epsilon_min + epsilon_max) / 2 free_space = calculate_free_space(curve1, curve2, epsilon) reachable = calculate_reachable_space(free_space) path = find_monotone_path(reachable) if path is not None: epsilon_max = epsilon final_path = path else: epsilon_min = epsilon return epsilon_max, final_path