Skip to content

Koch

The Koch curve as the L-system F → F+F--F+F drawn by a turtle.

  • Name: koch_curve
  • Field: mathematics/fractals
  • Formalism: rewriting system
  • References: Prusinkiewicz and Lindenmayer 1990; Thurner, Hanel, and Klimek 2018; Trzaska 2023

Factory

@register_model(
    field='mathematics/fractals',
    tags=('fractal', 'L-system', 'rewriting system', 'turtle'),
    references=('Prusinkiewicz and Lindenmayer 1990', 'Thurner, Hanel, and Klimek 2018', 'Trzaska 2023'),
    defaults={'compiler': RewritingCompiler(), 'until': 5, 'dt': 1},
)
def koch_curve(angle: float = 60.0) -> System:
    """Return the Koch curve as the L-system `F → F+F--F+F` drawn by a turtle.

    Every generation replaces each segment by four segments of a third of its length, with a bump of the turning angle
    in the middle. With the angle of 60 degrees the curve keeps its endpoints at `(0, 0)` and `(1, 0)`, its length is
    `(4/3)^n` at generation `n`, and its similarity dimension is `log 4 / log 3`, about 1.262.

    Args:
        angle:
            The turning angle of the turtle in degrees.

    Returns:
        system:
            The model, with the word `koch`, its symbol counts `koch.F`, and its size `koch.size`.

    Examples:
        >>> from skcomplex.models import run
        >>> run('koch_curve', settings={'until': 3}).trajectory_.values('koch.F').tolist()
        [1.0, 4.0, 16.0, 64.0]
    """
    word = KochElement(
        'koch',
        axiom='F',
        alphabet='F+-',
        geometry=GeometrySpec(angle=angle, step=1.0, contraction=1 / 3),
        bounds=(-0.03, -0.05, 1.03, 0.35),
    )
    return System(elements=[word])

Components

class KochElement(WordElement):
    """Word rewritten by the production `F → F+F--F+F` of the Koch curve.

    Args:
        label:
            The label of the word.

        axiom:
            The word at generation 0.

        geometry:
            How the word is drawn as line segments, or `None` for no geometry.

    Examples:
        >>> from skcomplex.models.mathematics.fractals import KochElement
        >>> KochElement('koch', axiom='F')._get_laws(None)[0].successor
        'F+F--F+F'
    """

    def _get_laws(self, s: SimpleNamespace) -> list[ProductionLaw]:
        """Return the production of the Koch curve.

        Args:
            s:
                The namespace of the symbols the laws can use.

        Returns:
            laws:
                The production of the word.
        """
        del s
        return [ProductionLaw('F', 'F+F--F+F')]