Beispiel #1
0
    def __init__(self, lines, verbose=True):
        self._lines = []
        self.verbose = verbose

        if isinstance(lines, Link):
            self.lines = [Knot(line) for line in lines.lines]
        else:
            lines = [Knot(line) for line in lines]
            self.lines = lines

        self._crossings = None
        self._gauss_code = {}

        self._recent_octree = None
Beispiel #2
0
def k4_1(num_points=100):
    '''Returns a particular figure eight knot conformation.'''
    data = n.zeros((num_points, 3), dtype=n.float64)
    ts = n.linspace(0, 2 * n.pi, num_points)
    data[:, 0] = (2 + n.cos(2 * ts)) * n.cos(3 * ts)
    data[:, 1] = (2 + n.cos(2 * ts)) * n.sin(3 * ts)
    data[:, 2] = n.sin(4 * ts)
    return Knot(data)
Beispiel #3
0
def unknot(num_points=100):
    '''Returns a simple circle.'''
    data = n.zeros((num_points, 3), dtype=n.float64)
    ts = n.linspace(0, 2 * n.pi, num_points)
    data[:, 0] = 3 * n.sin(ts)
    data[:, 1] = 3 * n.cos(ts)
    data[:, 2] = n.sin(3 * ts)
    return Knot(data)
Beispiel #4
0
    def octree_simplify(self,
                        runs=1,
                        plot=False,
                        rotate=True,
                        obey_knotting=False,
                        **kwargs):
        '''
        Simplifies the curves via the octree reduction of
        :module:`pyknotid.simplify.octree`.

        Parameters
        ----------
        runs : int
            The number of times to run the octree simplification.
            Defaults to 1.
        plot : bool
            Whether to plot the curve after each run. Defaults to False.
        rotate : bool
            Whether to rotate the space curve before each run. Defaults
            to True as this can make things much faster.
        obey_knotting : bool
            Whether to not let the line pass through itself. Defaults to
            False - knotting of individual components will be ignored!
            This is *much* faster than the alternative.

        kwargs are passed to the :class:`pyknotid.simplify.octree.OctreeCell`
        constructor.
        '''
        from ..simplify.octree import OctreeCell, remove_nearby_points
        for line in self.lines:
            line.points = remove_nearby_points(line.points)
        for i in range(runs):
            if n.sum([len(knot.points) for knot in self.lines]) > 30:
                vprint(
                    '\rRun {} of {}, {} points remain'.format(
                        i, runs, len(self)), False, self.verbose)

            if rotate:
                rot_mat = get_rotation_matrix(n.random.random(3))
                for line in self.lines:
                    line._apply_matrix(rot_mat)

            oc = OctreeCell.from_lines([line.points for line in self.lines],
                                       **kwargs)
            oc.simplify(obey_knotting)
            self._recent_octree = oc
            self.lines = [Knot(line) for line in oc.get_lines()]
            for line in self.lines:
                line.points = remove_nearby_points(line.points)

            if rotate:
                for line in self.lines:
                    line._apply_matrix(rot_mat.T)

            if plot:
                self.plot()

        vprint('\nReduced to {} points'.format(len(self)))
Beispiel #5
0
def lissajous(nx=3, ny=2, nz=7, px=0.7, py=0.2, pz=0., num_points=100):
    '''Returns a `Lissajous knot
    <https://en.wikipedia.org/wiki/Lissajous_knot>`__ with the given
    parameters.'''
    data = n.zeros((num_points, 3), dtype=n.float64)
    ts = n.linspace(0, 2 * n.pi, num_points)
    data[:, 0] = n.cos(nx * ts + px)
    data[:, 1] = n.cos(ny * ts + py)
    data[:, 2] = n.cos(nz * ts + pz)
    return Knot(data)
Beispiel #6
0
def knot_from_text(text):

    points = []
    for line in text.split('\n'):
        values = line.split(' ')
        if len(values) == 1 and len(values[0]) == 0:
            continue
        if len(values) != 3:
            raise ValueError('Invalid text passed.')
        points.append([float(v) for v in values])

    k = Knot(points, verbose=False)
    return k
Beispiel #7
0
def torus_knot(p=3, q=4, num=100):
    '''
    Returns points in the p, q torus knot. If p and q are not coprime,
    returns only the first component.

    Parameters
    ----------
    p : int
        The number of times the knot winds around the outside of the
        torus. Defaults to 3.
    q : int
        The number of times the knot passes through the hole in the
        centre of the torus. Defaults to 4.
    num_points : int
        The number of points in the returned piecewise linear
        curve. If there are multiple curves (i.e. a torus link), this
        is the number of points in *each* curve.  Defaults to 100.
    '''
    return Knot(
        TorusKnot(p, q, num, minor_radius=1.5, major_radius=3).first_component)
Beispiel #8
0
    def from_periodic_lines(cls, lines, shape, perturb=True):
        '''Returns a :class:`Link` instance in which the lines have
        been unwrapped through the periodic boundaries.

        Parameters
        ----------
        line : list
            A list of the Nx3 vectors of points in the lines
        shape : array-like
            The x, y, z distances of the periodic boundary
        perturb : bool
            If True, translates and rotates the knot to avoid any lattice
            problems.
        '''
        shape = ensure_shape_tuple(shape)
        lines = [
            Knot.from_periodic_line(line, shape, perturb=False)
            for line in lines
        ]
        link = cls(lines)
        if perturb:
            link.translate(n.array([0.00123, 0.00231, 0.00321]))
            link.rotate()
        return link