Esempio n. 1
0
 def tikz_code(self, pspict=None):
     from yanntricks.src.NoMathUtilities import logging
     symbol_dict = {}
     symbol_dict[None] = "$\\bullet$"
     symbol_dict["*"] = "$\\bullet$"
     symbol_dict["|"] = "$|$"
     symbol_dict["x"] = "$\\times$"
     symbol_dict["o"] = "$o$"
     symbol_dict["diamond"] = "$\diamondsuit$"
     try:
         effective_symbol = symbol_dict[self.parameters.symbol]
     except KeyError:
         effective_symbol = self.parameters.symbol
     if self.parameters.symbol == 'none':
         logging("You should use '' instead of 'none'", pspict=pspict)
     if self.parameters.symbol not in ["none", ""]:
         s = "\draw [{2}]  {0} node [rotate={3}] {{{1}}};".format(
             self.coordinates(digits=5, pspict=pspict), effective_symbol,
             self.params(language="tikz", refute=["symbol", "dotangle"]),
             "DOTANGLE")
         if self.parameters.dotangle != None:
             s = s.replace("DOTANGLE", str(self.parameters.dotangle))
         else:
             s = s.replace("DOTANGLE", "0")
         return s
     return ""
Esempio n. 2
0
    def id_values_dict(self):
        """
        Build the dictionary of stored values in the auxiliary file
        and rewrite that file.
        """
        d = {}
        try:
            f = open(self.interWriteFile.from_sage(), "r")
        except IOError:
            if not self.already_warned_CompileYourLaTeXFile:
                logging(
                    f"Warning: the auxiliary file "
                    f"{self.interWriteFile.from_main()} does not "
                    f"seem to exist. Compile your LaTeX file.",
                    pspict=self.picture)
                self.already_warned_CompileYourLaTeXFile = True
            return d
        idlist = f.read().replace('\n', '').replace(' ',
                                                    '').replace('\\par',
                                                                '').split("-")
        f.close()

        for els in idlist[0:-1]:
            key = els.split(":")[0]
            value = els.split(':')[1]
            d[key] = value

        with open(self.interWriteFile.from_sage(), "w") as f:
            for k in d:
                f.write("%s:%s-\n" % (k, d[k]))

        return d
 def __sub__(self, other):
     try:
         s = AngleMeasure(value_radian=self.radian - other.radian)
     except AttributeError:
         from yanntricks.src.NoMathUtilities import logging
         logging(
             "Are you trying to add an 'AngleMesasure' with something else ?"
         )
         logging("'other's type is " + str(type(other)))
         raise
     return s
    def __add__(self, other):
        ##
        # return the sum of two angles.
        # The return type is `AngleMeasure`

        try:
            return AngleMeasure(value_radian=self.radian + other.radian)
        except AttributeError:
            from yanntricks.src.NoMathUtilities import logging
            logging(
                "Are you trying to add an 'AngleMeasure' with something else ?"
            )
            logging("The other's type is " + str(type(other)))
            raise
Esempio n. 5
0
    def put_mark(self,
                 dist=None,
                 angle=None,
                 text="",
                 mark_point=None,
                 added_angle=None,
                 position=None,
                 pspict=None,
                 pspicts=None):
        """
        Put a mark on an object


        If you want to put a mark on an object
        P.put_mark(0.1,text="foobar",pspict=pspict,position="N")

        mark_point is a function which returns the
        position of the mark point.

        If you give no position (i.e. no "S","N", etc.) the position will
        be automatic regarding the angle.

        - ``angle`` is given in degree.
        set `position` to "center" is dangerous because
        it puts the center of the box at given angle and distance.
        Thus the text can be ill placed, especially if the given
        `dist` is lower than the half of the box size.

        `center_direction` : the mark is placed in such a way
        that the center is at given angle, and the box's border
        at given distance.
        """
        pspicts = make_psp_list(pspict, pspicts)

        for psp in pspicts:
            mark = self.get_mark(dist,
                                 angle,
                                 text,
                                 mark_point=mark_point,
                                 added_angle=added_angle,
                                 position=position,
                                 pspict=psp)

            if position in ["N", "S", "E", "W"] and angle is not None:
                logging("When you want a position like N,S,E, or W,\
                        the mark angle should not be given.")
            self.added_objects.append(psp, mark)

        self.mark = mark
Esempio n. 6
0
def visual_vector(v, pspict=None, xunit=None, yunit=None):
    """
    Return a vector which will be visually `self`.

    Return a vector at the same base as 'v' but such that
    it will visually appears as 'v'
    """
    from yanntricks.src.NoMathUtilities import logging
    from yanntricks.src.affine_vector import AffineVector
    if pspict is None and (xunit is None or yunit is None):
        logging("Trying to make visual_vector with no pspict ?")
        raise DeprecationWarning
    if pspict:
        xunit = pspict.xunit
        yunit = pspict.yunit
    I = v.I
    F = I + (v.Dx / xunit, v.Dy / yunit)
    return AffineVector(I, F)
Esempio n. 7
0
    def is_almost_equal(self, other, epsilon=0.0001):
        ##
        #   return true if `self` and `other` have coordinates difference
        #   lower than `epsilon`
        #
        from yanntricks.src.NoMathUtilities import logging

        if not isinstance(other, Point):
            logging("We are comparing " + type(self) + " with " + type(other) +
                    ". We continue, but this is strange.")

        sx = numerical_approx(self.x)
        sy = numerical_approx(self.y)
        ox = numerical_approx(other.x)
        oy = numerical_approx(other.y)

        if abs(sx - ox) > epsilon:
            return False
        if abs(sy - oy) > epsilon:
            return False
        return True
Esempio n. 8
0
    def get_Id_value(self, Id, default_value=0):
        if Id not in self.id_values_dict():

            if not self.already_warned_CompileYourLaTeXFile:
                logging(self.picture.name + "-----")
                logging(
                    f"Warning: the auxiliary file "
                    f"{self.interWriteFile.from_main()} does not "
                    f"contain the id «{Id}». Compile your LaTeX file.",
                    pspict=self.picture)
                try:
                    logging("Concerned tex expression : "
                            f"{self.interId_to_tex_expression[Id]}")
                except KeyError:
                    pass  # when asking for a counter, not a box size.

                self.already_warned_CompileYourLaTeXFile = True
            return default_value
        value = self.id_values_dict()[Id]
        return value
Esempio n. 9
0
    def get_mark(self,
                 dist,
                 angle=None,
                 text=None,
                 mark_point=None,
                 added_angle=None,
                 position=None,
                 pspict=None):
        # pylint:disable=too-many-branches
        """
        - `angle` is degree or AngleMeasure

        In the internal representation of the mark,
        the angle type will be `AngleMeasure`
        """
        from yanntricks.src.Constructors import Mark
        from yanntricks.src.AngleMeasure import AngleMeasure

        self.marque = True

        if position in ["N", "S", "E", "W"] and angle is not None:
            angle = None
            logging(
                f"When you want a position like N,S,E, or W, "
                f"the mark angle should not be given.",
                pspict=pspict)

        if angle is None and position not in ["N", "S", "E", "W"]:
            try:
                angle = self.advised_mark_angle(pspict=pspict)
            except AttributeError:
                angle = self.angle().degree + 90

        if position == "center_direction":
            # In this case we assume 'self' is a point
            angle = angle.degree

        if isinstance(angle, AngleMeasure):
            angle = angle.degree

        # At this point, 'angle' has to be degree,
        # - for the possibility of "added_angle"
        # - the constructor of 'mark' expects degree or AngleMeasure

        if added_angle:
            angle = angle + added_angle
        if position is None:
            position = "corner"
            alpha = AngleMeasure(value_degree=angle).positive()
            deg = alpha.degree
            if deg == 0:
                position = "W"
            if deg == 90:
                position = "S"
            if deg == 180:
                position = "E"
            if deg == 180 + 90:
                position = "N"

        if position in ["N", "S", "E", "W"]:
            angle = None

        mark = Mark(graph=self,
                    dist=dist,
                    angle=angle,
                    central_point=None,
                    text=text,
                    mark_point=mark_point,
                    position=position,
                    pspict=pspict)

        # In each .psttricks file we need the lines that make compute
        # the size of the text. Thus we call "get_box_size" for each.
        if not isinstance(pspict, list):
            pspict = [pspict]
        for psp in pspict:
            _, _ = psp.get_box_size(text)

        return mark
Esempio n. 10
0
    def get_mark(self,
                 dist=None,
                 angle=None,
                 text=None,
                 mark_point=None,
                 added_angle=None,
                 position=None,
                 pspict=None,
                 visual_work=True):
        from yanntricks.src.Visual import visual_point
        from yanntricks.src.Constructors import Mark
        if text == "" or text is None:
            logging(
                "This is very strange to require a mark with an empty text. Maybe you'll get a crash on the second pass."
            )

        if visual_work:
            v_angle = inverse_visual_angle(self, pspict)

            old_xunit = pspict.xunit
            old_yunit = pspict.yunit
            pspict.xunit = 1
            pspict.yunit = 1
            mark = v_angle.get_mark(dist=dist,
                                    angle=angle,
                                    text=text,
                                    mark_point=mark_point,
                                    added_angle=added_angle,
                                    position=position,
                                    pspict=pspict,
                                    visual_work=False)
            pspict.xunit = old_xunit
            pspict.yunit = old_yunit
            cp = visual_point(mark.central_point(), pspict)
            return Mark(self,
                        dist=None,
                        angle=None,
                        text=text,
                        mark_point=None,
                        central_point=cp,
                        position=None,
                        pspict=pspict)

        mark_point = self.mark_point(pspict)

        if position != None:
            print(
                "The mark of an angle should be given without position argument"
            )
            raise

        # The default can be any value different than zero. It serves to
        # avoid a division by zero during the first compilation.
        dimx, dimy = pspict.get_box_size(text, default_value="3pt")

        # Now there are a lot of cases depending on the angles of the
        # two lines determining the angle AOB.
        # We will detail the computations for the case
        #  0<self.angleA.degree < 90 and 0<self.angleB.degree < 90
        # The other cases are the same kind of trigonometry.
        # I just let you know that if you know 3 angles and one length
        # in a triangle, you know everything :
        # just draw the altitude and use Pythagoras along with some
        # trigonometry.

        # The cases are tested in the demo files
        # 'OMPAooMbyOIqeA' and 'Refraction'

        v = self._getOCvector(dimx, dimy, pspict=pspict)

        # If 'dist' is given, it overrides the computations of the
        # length of 'v'
        if dist is not None:
            if dist < v.length:
                logging("The distance you give is {} while I computed\
                        the minimal to be {}".format(dist, v.length),
                        pspict=pspict)
            v = v.normalize(dist)

        # We impose a minimum for the v's length.
        # If the 'text' is small and the angle is large, its box is really
        # close to the angles'vertex. Thus the text will be very close to
        # the arc circle and the result is bad.
        # Thus we impose a minimal distance between the
        # arc circle and the mark.
        if dist is None:
            if v.length < 0.3:
                v = v.normalize(0.3)

        C = mark_point.translate(v)

        return Mark(self,
                    dist=None,
                    angle=None,
                    text=text,
                    mark_point=None,
                    central_point=C,
                    position=None,
                    pspict=pspict)