Exemplo n.º 1
0
    def plot(self, model='UHP'):
        r"""
        Plot the frieze as an ideal hyperbolic polygon.

        This is only defined up to isometry of the hyperbolic plane.

        We are identifying the boundary of the hyperbolic plane with the
        real projective line.

        The option ``model`` must be one of

        * ``'UHP'`` - (default) for the upper half plane model
        * ``'PD'`` - for the Poincare disk model
        * ``'KM'`` - for the Klein model

        The hyperboloid model is not an option as this does not implement
        boundary points.

        .. PLOT::
            :width: 400 px

            t = path_tableaux.FriezePattern([1,2,7,5,3,7,4,1])
            sphinx_plot(t.plot())

        EXAMPLES::

            sage: t = path_tableaux.FriezePattern([1,2,7,5,3,7,4,1])
            sage: t.plot()
            Graphics object consisting of 18 graphics primitives

            sage: t.plot(model='UHP')
            Graphics object consisting of 18 graphics primitives

            sage: t.plot(model='PD')
            Traceback (most recent call last):
            ...
            TypeError: '>' not supported between instances of 'NotANumber' and 'Pi'
            sage: t.plot(model='KM')
            Graphics object consisting of 18 graphics primitives
        """
        from sage.geometry.hyperbolic_space.hyperbolic_interface import HyperbolicPlane
        from sage.plot.plot import Graphics
        models = {
            'UHP': HyperbolicPlane().UHP(),
            'PD': HyperbolicPlane().PD(),
            'KM': HyperbolicPlane().KM(),
        }
        if model not in models:
            raise ValueError(f"{model} must be one of ``UHP``, ``PD``, ``KM``")
        M = models[model]

        U = HyperbolicPlane().UHP()
        cd = CylindricalDiagram(self).diagram
        num = cd[0][:-1]
        den = cd[1][2:]
        vt = [M(U.get_point(x / (x + y))) for x, y in zip(num, den)]
        gd = [M.get_geodesic(vt[i - 1], vt[i]) for i in range(len(vt))]
        return sum([a.plot() for a in gd], Graphics()).plot()
Exemplo n.º 2
0
    def is_integral(self):
        r"""
        Return ``True`` if all entries of the frieze pattern are
        positive integers.

        EXAMPLES::

            sage: path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).is_integral()
            True

            sage: path_tableaux.FriezePattern([1,3,4,5,1]).is_integral()
            False
        """
        n = len(self)
        cd = CylindricalDiagram(self).diagram
        return all(all(k in ZZ for k in a[i+1:n+i-2]) for i, a in enumerate(cd))
Exemplo n.º 3
0
    def triangulation(self):
        r"""
        Plot a regular polygon with some diagonals.

        If ``self`` is positive and integral then this will be a triangulation.

        .. PLOT::
            :width: 600 px

            G = path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).triangulation()
            p = graphics_array(G, 7, 6)
            sphinx_plot(p)

        EXAMPLES::

            sage: path_tableaux.FriezePattern([1,2,7,5,3,7,4,1]).triangulation()
            Graphics object consisting of 25 graphics primitives

            sage: path_tableaux.FriezePattern([1,2,1/7,5,3]).triangulation()
            Graphics object consisting of 12 graphics primitives

            sage: K.<sqrt2> = NumberField(x^2-2)
            sage: path_tableaux.FriezePattern([1,sqrt2,1,sqrt2,3,2*sqrt2,5,3*sqrt2,1], field=K).triangulation()
            Graphics object consisting of 24 graphics primitives
        """
        n = len(self) - 1
        cd = CylindricalDiagram(self).diagram
        from sage.plot.plot import Graphics
        from sage.plot.line import line
        from sage.plot.text import text
        from sage.functions.trig import sin, cos
        from sage.all import pi
        G = Graphics()
        G.set_aspect_ratio(1.0)

        vt = [(cos(2 * theta * pi / (n)), sin(2 * theta * pi / (n)))
              for theta in range(n + 1)]
        for i, p in enumerate(vt):
            G += text(str(i), [1.05 * p[0], 1.05 * p[1]])

        for i, r in enumerate(cd):
            for j, a in enumerate(r[:n]):
                if a == 1:
                    G += line([vt[i], vt[j]])

        G.axes(False)
        return G