# Path: lfd/rapprentice/knot_identification.py
# def intersect_segs(ps_n2, q_22):
#     def cross(a_n2, b_n2):
# def rope_has_intersections(ctl_pts):
# def compute_dt_code(ctl_pts, plotting=False):
# def _dt_code_to_knot(dt_code):
# def dt_code_to_knot(dt_code):
#     def dt_code_to_knot_wrapper(q, x):
# def identify_knot(ctl_pts):
# def main():
#     TIMEOUT = 1


import networkx as nx, numpy as np, scipy.spatial.distance as ssd, scipy.interpolate as si
import itertools
    import matplotlib.pyplot as plt; plt.ion()
from collections import deque
from numpy.random import rand
from lfd.rapprentice import knot_identification
        from mayavi import mlab
        from mayavi import mlab
    from mayavi import mlab
    total_path = []
    for node in nodes[::2]:
        if node%2 == 0: total_path.extend(segs[node//2])
        else: total_path.extend(segs[node//2][::-1])

    total_path_3d = remove_duplicate_rows(np.array([S.node[i]["xyz"] for i in total_path]))

    # perturb the path, if requested
    if perturb_peak_dist is not None and perturb_peak_dist != 0:
        print "Perturbing the Path"
        orig_path_length = np.sqrt(((total_path_3d[1:,:2] - total_path_3d[:-1,:2])**2).sum(axis=1)).sum()
        perturb_centers = np.linspace(0, len(total_path_3d)-1, num_perturb_points).astype(int)
        perturb_xy = np.zeros((len(total_path_3d), 2))
        bandwidth = len(total_path_3d) / (num_perturb_points-1)

        # add a linearly decreasing peak around each perturbation center
        # (keep doing so randomly until our final rope has no loops)
        for _ in range(20):
            for i_center in perturb_centers:
                angle = np.random.rand() * 2 * np.pi
                range_min = max(0, i_center - bandwidth)
                range_max = min(len(total_path_3d), i_center + bandwidth + 1)

                radii = np.linspace(0, perturb_peak_dist, i_center+1-range_min)
                perturb_xy[range_min:i_center+1,:] += np.c_[radii*np.cos(angle), radii*np.sin(angle)]

                radii = np.linspace(perturb_peak_dist, 0, range_max-i_center)
                perturb_xy[i_center+1:range_max,:] += np.c_[radii*np.cos(angle), radii*np.sin(angle)][1:,:]

            unscaled_path_2d = total_path_3d[:,:2] + perturb_xy

# Path: lfd/rapprentice/knot_identification.py
# def intersect_segs(ps_n2, q_22):
#     def cross(a_n2, b_n2):
# def rope_has_intersections(ctl_pts):
# def compute_dt_code(ctl_pts, plotting=False):
# def _dt_code_to_knot(dt_code):
# def dt_code_to_knot(dt_code):
#     def dt_code_to_knot_wrapper(q, x):
# def identify_knot(ctl_pts):
# def main():
#     TIMEOUT = 1


# Path: lfd/rapprentice/rope_initialization.py
import networkx as nx, numpy as np, scipy.spatial.distance as ssd, scipy.interpolate as si
import itertools
    import matplotlib.pyplot as plt; plt.ion()
from collections import deque
from numpy.random import rand
from lfd.rapprentice import knot_identification
        from mayavi import mlab
        from mayavi import mlab
    from mayavi import mlab

    total_path = []
    for node in nodes[::2]:
        if node%2 == 0: total_path.extend(segs[node//2])
        else: total_path.extend(segs[node//2][::-1])

    total_path_3d = remove_duplicate_rows(np.array([S.node[i]["xyz"] for i in total_path]))

    # perturb the path, if requested
    if perturb_peak_dist is not None and perturb_peak_dist != 0:
        print "Perturbing the Path"
        orig_path_length = np.sqrt(((total_path_3d[1:,:2] - total_path_3d[:-1,:2])**2).sum(axis=1)).sum()
        perturb_centers = np.linspace(0, len(total_path_3d)-1, num_perturb_points).astype(int)
        perturb_xy = np.zeros((len(total_path_3d), 2))
        bandwidth = len(total_path_3d) / (num_perturb_points-1)

        # add a linearly decreasing peak around each perturbation center
        # (keep doing so randomly until our final rope has no loops)
        for _ in range(20):
            for i_center in perturb_centers:
                angle = np.random.rand() * 2 * np.pi
                range_min = max(0, i_center - bandwidth)
                range_max = min(len(total_path_3d), i_center + bandwidth + 1)

                radii = np.linspace(0, perturb_peak_dist, i_center+1-range_min)
                perturb_xy[range_min:i_center+1,:] += np.c_[radii*np.cos(angle), radii*np.sin(angle)]

                radii = np.linspace(perturb_peak_dist, 0, range_max-i_center)
                perturb_xy[i_center+1:range_max,:] += np.c_[radii*np.cos(angle), radii*np.sin(angle)][1:,:]

            unscaled_path_2d = total_path_3d[:,:2] + perturb_xy

            if not knot_identification.rope_has_intersections(unscaled_path_2d):