6

I would like to have two new decorated triangles. This si for writing an exercice about B-Method in a mathematical formulas.

Examples

Vincent
  • 20,157
projetmbc
  • 13,315
  • 3
    You should probably explain how these symbols are to be used (maybe in mathematical formulas as binary relations, etc.). – frougon Apr 08 '20 at 09:51
  • I have updated my question. Thanks for your comment. :-) – projetmbc Apr 08 '20 at 10:00
  • 1
    One answer has interpreted some of the "additions" as being colored. Is this an artifact, or intentional? Please add a note to your question specifying whether the symbols should be monochromatic or parti-colored. – barbara beeton Apr 08 '20 at 16:07
  • Indeed, the triangles are black but the “inner features” of the symbols in the second and third rows are colored in brown, precisely with color #714d4d in HTML notation (RGB). – frougon Apr 08 '20 at 16:10

4 Answers4

7

Since the image in the question uses different colors inside the same symbol, I propose a flexible interface that allows one to choose specific settings (via TikZ styles) for the triangle and for the “inner feature” (which can be empty, a plus sign or a horizontal bar). The operator defined below behaves as a binary relation (\mathrel). The left or right triangle vertex is at the height of the math axis (i.e., at the same level as fraction bars, \cdots, + and = signs). I implemented two interfaces:

  • the verbose one: \myTriangle takes one optional argument which consists of PGF keys executed in /tikz/my triangle (e.g., \myTriangle[orientation=right, inner feature type=+, append style={fill=yellow}, append inner feature style={draw=red}]);

  • the terse one: \mytriangle[triangle opts][inner feature opts]{l}{+} or \mytriangle[triangle opts][inner feature opts]{r}{-}, etc. (if the last argument is empty or blank, the triangle will be empty).

Both interfaces are illustrated in the examples below. The color of the “inner feature” is brown by default, since this is how it is in the question. This default can be changed by simple modification of the following line:

set inner feature style={draw=brown, line cap=round, line width=0.3pt}

You can choose the default TikZ settings you want independently for the triangle and for the inner feature using the keys defined in the first \tikzset command of my code. The very same options can be used in the optional argument of \myTriangle.

\documentclass[border=0.5mm]{standalone}
\usepackage{tikz}
\usepackage{xparse} % for the interface allowing concise syntax (\mytriangle)

\makeatletter
\newif\ifmy@triangle@orientation@left
\newif\ifmy@triangle@twosides

\tikzset{
  my triangle/.is family,
  my triangle/.cd,
  set style/.style={style/.style={#1}}, % store for future use
  append style/.style={style/.append style={#1}},
  set style={draw=black, line width=0.3pt},
  inner feature type/.store in=\my@triangle@feature@type,
  inner feature type={},
  set inner feature style/.style={inner feature style/.style={#1}},
  append inner feature style/.style={inner feature style/.append style={#1}},
  set inner feature style={draw=brown, line cap=round, line width=0.3pt},
  orientation/.is choice,
  orientation/left/.code={\my@triangle@orientation@lefttrue},
  orientation/right/.code={\my@triangle@orientation@leftfalse},
  orientation=left,
  transform/.style={},  % semi-private: use only if you understand how it works
}

% Command from egreg (https://tex.stackexchange.com/a/499972/73317)
\newcommand{\math@param}[3]{%
  \fontdimen#3
  \ifx#1\displaystyle\textfont#2
  \else\ifx#1\textstyle\textfont#2
  \else\ifx#1\scriptstyle\scriptfont#2
  \else\scriptscriptfont#2 \fi\fi\fi
}

% #1: Either \my@triangle@left or \my@triangle@right
\newcommand*{\my@triangle@wrap}[1]{%
  \ifx\my@triangle@feature@type\empty
    \my@triangle@twosidesfalse
  \else
    \if\my@triangle@feature@type -%
      \my@triangle@twosidesfalse
    \else
      \if\my@triangle@feature@type +%
        \my@triangle@twosidestrue
      \else
        \errmessage{%
          Unexpected triangle feature type: '\my@triangle@feature@type'}%
      \fi
    \fi
  \fi
  \mathrel{\mathpalette#1\relax}%
}

\newcommand*{\my@triangle@width}{2} % multiple of the math axis height
\newdimen\my@height

% #1: math style
% #2: unused
\newcommand*{\my@triangle@left}[2]{%
  \my@height=\math@param{#1}{2}{22}% height of the math axis
  \begin{tikzpicture}[scale=\my@height/1cm, my triangle/transform]
    \path[my triangle/style, draw=none]
      (0,1) -- (\my@triangle@width,2) -- (\my@triangle@width,0) -- cycle;

    \ifx\my@triangle@feature@type\empty
    \else
      \begin{scope}[every path/.append style={my triangle/inner feature style}]
        \if\my@triangle@feature@type -
          \path (0,1) -- (\my@triangle@width,1);
        \else
          \if\my@triangle@feature@type +
            \path (\my@triangle@width-0.5, 1) -- (\my@triangle@width+0.5, 1)
                  (\my@triangle@width, 0.5) -- (\my@triangle@width, 1.5);
          \fi
        \fi
      \end{scope}
    \fi

    \path[my triangle/style, fill=none]
      (\my@triangle@width,0) -- (0,1) -- (\my@triangle@width,2)
      \ifmy@triangle@twosides \else --cycle \fi;
  \end{tikzpicture}%
}

\newcommand*{\my@triangle@right}{%
  \tikzset{my triangle/transform/.append style={xscale=-1}}%
  \my@triangle@left
}

% #1: PGF keys executed in '/tikz/my triangle'
\newcommand*{\myTriangle}[1][]{%
  \begingroup
    \tikzset{my triangle/.cd, #1}%
    \expandafter\expandafter\expandafter\my@triangle@wrap
    \ifmy@triangle@orientation@left
      \expandafter\my@triangle@left
    \else
      \expandafter\my@triangle@right
    \fi
  \endgroup
}
\makeatother

% Offer an interface that allows concise syntax
\ExplSyntaxOn
\msg_new:nnn { mytriangle } { invalid-orientation-arg }
  { Invalid~value~for~triangle~orientation:~'#1'. }
\msg_new:nnn { mytriangle } { invalid-feature-type }
  { Invalid~feature~type:~'#1'. }

\tl_new:N \l__mytriangle_orientation_tl
\tl_new:N \l__mytriangle_feature_type_tl

% #1: passed to '/tikz/my triangle/append style'
% #2: passed to '/tikz/my triangle/append inner feature style'
% #3: orientation ('l', 'r')
% #4: inner feature type ('' or ' ', '-', '+')
\NewDocumentCommand \mytriangle { O{} O{} m m }
  {
    \str_case_e:nnF {#3}
      {
        { l } { \tl_set:Nn \l__mytriangle_orientation_tl { left } }
        { r } { \tl_set:Nn \l__mytriangle_orientation_tl { right } }
      }
      { \msg_error:nnn { mytriangle } { invalid-orientation-arg } {#3} }

    \tl_if_blank:nTF {#4}
      { \tl_clear:N \l__mytriangle_feature_type_tl }
      {
        \str_case_e:nnF {#4}
          {
            { - } { \tl_set:Nn \l__mytriangle_feature_type_tl { - } }
            { + } { \tl_set:Nn \l__mytriangle_feature_type_tl { + } }
          }
          { \msg_error:nnn { mytriangle } { invalid-feature-type } {#4} }
      }

    \myTriangle
      [
        append~style={#1}, append~inner~feature~style={#2},
        orientation/.expand~once=\l__mytriangle_orientation_tl,
        inner~feature~type/.expand~once=\l__mytriangle_feature_type_tl,
      ]
  }
\ExplSyntaxOff

\begin{document}

$\begin{array}{@{}l@{}}
a \mytriangle{l}{} b \mytriangle{l}{-} c \mytriangle{l}{+} d
\\
a \mytriangle{r}{} b \mytriangle{r}{-} c \mytriangle{r}{+} d
\\
a \myTriangle[append style={fill=yellow}, inner feature type=-] b
\mytriangle[fill=cyan!60!green][draw=black]{l}{+}
\mytriangle[fill=cyan][draw=yellow]{l}{-}
\mytriangle[fill=red]{l}{+}
\\
a \myTriangle[orientation=right, append style={draw=orange!50!red, fill=yellow},
              inner feature type=+, append inner feature style={draw=cyan}] b
\mytriangle[fill=cyan!60!green][draw=black]{r}{}
\mytriangle[fill=cyan][draw=yellow]{r}{-}
\mytriangle[fill=red]{r}{+}
\end{array}$

\end{document}

enter image description here

Example with subscripts and superscripts:

$\begin{array}{@{}l@{}}
M \mytriangle{l}{ } N
  ^{{\alpha \mytriangle{l}{-} \beta}^{\gamma \mytriangle{l}{+} \delta}}
  _{{\varepsilon \mytriangle{l}{-} \delta}_{\eta \mytriangle{l}{+} \kappa}}
\\[1ex]
M \mytriangle{r}{ } N
  ^{{\alpha \mytriangle{r}{-} \beta}^{\gamma \mytriangle{r}{+} \delta}}
  _{{\varepsilon \mytriangle{r}{-} \delta}_{\eta \mytriangle{r}{+} \kappa}}
\end{array}$

enter image description here

frougon
  • 24,283
  • 1
  • 32
  • 55
  • Interesting, but where do the colors come from? (I don't see them in the question.) – barbara beeton Apr 08 '20 at 15:45
  • @barbarabeeton Look closely: in the image from the question, the horizontal bar and + signs are colored in brown, precisely #714d4d in HTML notation (RGB). If the OP didn't want different colors for the triangle and inside the symbols, putting that image in the question and no text telling to ignore the colors is really... disrespectful behavior. – frougon Apr 08 '20 at 15:53
  • Okay, thanks. I don't see it, but my laptop is old, and may be deficient. (This is something the OP can be asked about; I'll add a comment.) – barbara beeton Apr 08 '20 at 16:05
  • 1
    Very very nice..... – Sebastiano Apr 08 '20 at 17:00
  • Thanks a lot for this tikz colored solution but to be honest it was not indented. Your solution is still very useful ! – projetmbc Apr 08 '20 at 17:05
  • @projetmbc Well, next time you post a question, please be careful about what you ask: when the description is only an image, this is the prescription. It has to be very accurate, otherwise people who answer will spend time “for nothing”... – frougon Apr 08 '20 at 17:23
  • @Sebastiano Thanks! I've modified the first example a little bit to better show how to use the various options. – frougon Apr 08 '20 at 17:26
  • @frougon -- I don't wish to raise a fuss, but I've had production experience where files submitted for publication carried unintended "color" artifacts like the one you spotted. Many graphics packages support color, and they often specify an RGB profile; that by definition can't produce true black -- that's possible only with CMYK. So if some element is created using a graphics technique, the very darkest option is used, but it's not black. Many graphics required color correction for printing. I believe that's what happened here. – barbara beeton Apr 08 '20 at 20:13
  • 1
    @barbarabeeton I trust you that weird things can happen with color profiles, but without knowing more about the origin of the image, I would favor a simpler explanation. In the image from the question, the triangles are more or less black (very dark gray); only the inner features (horizontal bar or + sign) on the second and third rows are brown. Thus, my guess would be that the inner features have been drawn over a screenshot that had triangles only, and maybe the OP didn't realize they picked a brown when adding the inner features. Anyway, it's done now... – frougon Apr 08 '20 at 22:14
  • @frougon You don't spend any time “for nothing” in that case because this will be also helpfull : I would like to define colored symbol to print icons of some programming languages like Python. PS: for the picture, I've used GeoGebra and didn't take care of it. Excuse me for this. – projetmbc Apr 09 '20 at 17:17
6

Geometric symbols: a job for l3draw.

\documentclass{article}
\usepackage{amsmath,xparse,l3draw}

\ExplSyntaxOn

\fp_new:N \l__pbmc_triangle_fp

\cs_new_protected:Nn \pmbc_triangle_right:
 {
  \draw_begin:
  \draw_linewidth:n { \l__pmbc_triangle_fp }
  \draw_cap_round:
  \draw_join_round:
  \draw_path_moveto:n { 0.0ex , 0.5ex }
  \draw_path_lineto:n { 1.0ex , 0.0ex }
  \draw_path_lineto:n { 1.0ex , 1.0ex }
  \draw_path_close:
  \draw_path_use_clear:n { stroke }
  \draw_end:
 }
\cs_new_protected:Nn \pmbc_triangle_left:
 {
  \draw_begin:
  \draw_linewidth:n { \l__pmbc_triangle_fp }
  \draw_cap_round:
  \draw_join_round:
  \draw_path_moveto:n { 0.0ex , 0.0ex }
  \draw_path_lineto:n { 1.0ex , 0.5ex }
  \draw_path_lineto:n { 0.0ex , 1.0ex }
  \draw_path_close:
  \draw_path_use_clear:n { stroke }
  \draw_end:
 }
\cs_new_protected:Nn \pmbc_triangle_minus_right:
 {
  \draw_begin:
  \draw_linewidth:n { \l__pmbc_triangle_fp }
  \draw_cap_round:
  \draw_join_round:
  \draw_path_moveto:n { 1.0ex , 0.5ex }
  \draw_path_lineto:n { 0.0ex , 0.5ex }
  \draw_path_lineto:n { 1.0ex , 1.0ex }
  \draw_path_lineto:n { 1.0ex , 0.0ex }
  \draw_path_lineto:n { 0.0ex , 0.5ex }
  \draw_path_close:
  \draw_path_use_clear:n { stroke }
  \draw_end:
 }
\cs_new_protected:Nn \pmbc_triangle_minus_left:
 {
  \draw_begin:
  \draw_linewidth:n { \l__pmbc_triangle_fp }
  \draw_cap_round:
  \draw_join_round:
  \draw_path_moveto:n { 0.0ex , 0.5ex }
  \draw_path_lineto:n { 1.0ex , 0.5ex }
  \draw_path_lineto:n { 0.0ex , 1.0ex }
  \draw_path_lineto:n { 0.0ex , 0.0ex }
  \draw_path_lineto:n { 1.0ex , 0.5ex }
  \draw_path_close:
  \draw_path_use_clear:n { stroke }
  \draw_end:
 }
\cs_new_protected:Nn \pmbc_triangle_plus_right:
 {
  \draw_begin:
  \draw_linewidth:n { \l__pmbc_triangle_fp }
  \draw_cap_round:
  \draw_join_round:
  \draw_path_moveto:n { 1.0ex , 1.0ex }
  \draw_path_lineto:n { 0.0ex , 0.5ex }
  \draw_path_lineto:n { 1.0ex , 0.0ex }
  \draw_path_use_clear:n { stroke }
  \draw_path_moveto:n { 1.0ex , 0.2ex }
  \draw_path_lineto:n { 1.0ex , 0.8ex }
  \draw_path_use_clear:n { stroke }
  \draw_path_moveto:n { 0.7ex, 0.5ex }
  \draw_path_lineto:n { 1.3ex, 0.5ex }
  \draw_path_use_clear:n { stroke }
  \draw_end:
 }
\cs_new_protected:Nn \pmbc_triangle_plus_left:
 {
  \draw_begin:
  \draw_linewidth:n { \l__pmbc_triangle_fp }
  \draw_cap_round:
  \draw_join_round:
  \draw_path_moveto:n { 0.0ex , 1.0ex }
  \draw_path_lineto:n { 1.0ex , 0.5ex }
  \draw_path_lineto:n { 0.0ex , 0.0ex }
  \draw_path_use_clear:n { stroke }
  \draw_path_moveto:n { 0.0ex , 0.2ex }
  \draw_path_lineto:n { 0.0ex , 0.8ex }
  \draw_path_use_clear:n { stroke }
  \draw_path_moveto:n { -0.3ex, 0.5ex }
  \draw_path_lineto:n { +0.3ex, 0.5ex }
  \draw_path_use_clear:n { stroke }
  \draw_end:
 }

\NewDocumentCommand{\BMright}{}
 {
  \mathrel
   {
    \fp_set:Nn \l__pmbc_triangle_fp { 0.08ex }
    \text{\kern0.1ex \pmbc_triangle_right: \kern0.1ex}
   }
 }
\NewDocumentCommand{\BMleft}{}
 {
  \mathrel
   {
    \fp_set:Nn \l__pmbc_triangle_fp { 0.08ex }
    \text{\kern0.1ex \pmbc_triangle_left: \kern0.1ex}
   }
 }
\NewDocumentCommand{\BMminusright}{}
 {
  \mathrel
   {
    \fp_set:Nn \l__pmbc_triangle_fp { 0.08ex }
    \text{\kern0.1ex \pmbc_triangle_minus_right: \kern0.1ex}
   }
 }
\NewDocumentCommand{\BMminusleft}{}
 {
  \mathrel
   {
    \fp_set:Nn \l__pmbc_triangle_fp { 0.08ex }
    \text{\kern0.1ex \pmbc_triangle_minus_left: \kern0.1ex}
   }
 }
\NewDocumentCommand{\BMplusright}{}
 {
  \mathrel
   {
    \fp_set:Nn \l__pmbc_triangle_fp { 0.08ex }
    \text{\kern0.1ex \pmbc_triangle_plus_right: \kern-0.2ex}
    \mkern2mu\nonscript\mkern-2mu
   }
 }
\NewDocumentCommand{\BMplusleft}{}
 {
  \mathrel
   {
    \fp_set:Nn \l__pmbc_triangle_fp { 0.08ex }
    \mkern2mu\nonscript\mkern-2mu
    \text{\kern-0.2ex \pmbc_triangle_plus_left: \kern0.1ex}
   }
 }

\ExplSyntaxOff

\begin{document}

$a \BMright b \BMleft c$

$a \BMminusright b \BMminusleft c$

$a \BMplusright b \BMplusleft c$

$\scriptstyle a \BMplusright b \BMplusleft c$

\LARGE $a \BMright b \BMleft c$

\end{document}

enter image description here

egreg
  • 1,121,712
4

Here's a simple implementation of these symbols. I'm not sure what this B-Method is, so I made them relational symbols with \mathrel so they behave like amsmath's \vartriangleleft and \vartriangleright symbols.

\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{trimclip}
\newlength{\trianglewidth}
\newlength{\pluswidth}
\settowidth{\trianglewidth}{\(\vartriangleleft\)}
\settowidth{\pluswidth}{\(+\)}
\newcommand{\lefttrianglebar}{%
    \mathrel{\makebox[\trianglewidth]{%
        \makebox[\trianglewidth]{\(\vartriangleleft\)}%
        \hspace*{-\trianglewidth}%
        \makebox[\trianglewidth]{\(-\)}%
    }}%
}
\newcommand{\righttrianglebar}{%
    \mathrel{\makebox[\trianglewidth]{%
        \makebox[\trianglewidth]{\(-\)}%
        \hspace*{-\trianglewidth}%
        \makebox[\trianglewidth]{\(\vartriangleright\)}%
    }}%
}
\newcommand{\lefttriangleplus}{%
    \mathrel{\makebox[\trianglewidth]{%
        \makebox[\trianglewidth]{\(<\)}%
        \hspace*{-.333\pluswidth}%
        \raisebox{.3\height}{\clipbox{.3\width{} .3\height}{\(+\)}}%
    }}%
}
\newcommand{\righttriangleplus}{%
    \mathrel{\makebox[\trianglewidth]{%
        \raisebox{.3\height}{\clipbox{.3\width{} .3\height}{\(+\)}}%
        \hspace*{-.333\pluswidth}%
        \makebox[\trianglewidth]{\(>\)}%
    }}%
}
\begin{document}
\( A \vartriangleleft  B \qquad A \vartriangleright B \)

\( A \lefttrianglebar  B \qquad A \righttrianglebar  B \)

\( A \lefttriangleplus B \qquad A \righttriangleplus B \)
\end{document}

Addendum

@barbarabeeton pointed out that the triangle symbols with a bar exist as Unicode symbols, and are included in the STIX font. With the stix package, they can be obtained as in the following example.

\documentclass{article}
\usepackage{stix}
\begin{document}
\begin{tabular}{ll}
    \( A \vartriangleleft  B \) & \( A \vartriangleright B \) \\
    \( A \rsub             B \) & \( A \dsub             B \)
\end{tabular}
\end{document}

I think they look somewhat too large, though. Maybe they would be better scaled down a little, to fit better with the other triangle symbols.

Sebastiano
  • 54,118
Vincent
  • 20,157
  • 2
    The triangles with the horizontal line are used in Z notation and in Unicode as 0x2A64 and 0xA65; they are in the STIX font, although I don't remember their TeX names. I think that the less and greater than with plus aren't in Unicode. – barbara beeton Apr 08 '20 at 13:47
  • @barbarabeeton Thanks! I was pretty sure I had already seen those somewhere, but I couldn't remember when or where, and Detexify doesn't find them. – Vincent Apr 08 '20 at 13:51
  • 3
    Try shapecatcher.com as an alternate lookup tool for symbols that might be in Unicode. (I believe that there's a link for this on the Detexify page.) It doesn't give the TeX name, but almost all "mathy" symbols in Unicode are in the STIX font, and that is covered in the Comprehensive Symbols List. – barbara beeton Apr 08 '20 at 14:00
  • Very cute and thanks for the unicode alternative to detextify. – projetmbc Apr 08 '20 at 14:11
  • @barbarabeeton Thanks for the tip! I also added another part to my answer about these symbols in the STIX font. – Vincent Apr 08 '20 at 14:16
1

You can define

\def\lefttrianglebar   {\mathbin{{\vartriangleleft}\mkern-14mu{-}}}
\def\righttrianglebar  {\mathbin{{-}\mkern-14mu{\vartriangleright}}}
\def\lefttriangleplus  {\mathbin{{<}\mkern-7mu{+}}}
\def\righttriangleplus {\mathbin{+\mkern-7mu>}}

And you can try this:

test: $a \lefttrianglebar b, c_{\righttrianglebar}$
\bye
wipet
  • 74,238