output::asciiArt – A domain for 2D ascii art graphics
This domain allows for creating 2D ascii art graphics, which can be displayed by the text pretty-printer of MuPAD.
Creating Elements
output::asciiArt([, ...])
Parameters:
, ...: |
Strings. |
Details:
A graphic g consists of a rectangle of characters, where the bottom left corner has coordinates [1,1], and the upper right corner has coordinates [g::dom::width(g), g::dom::height(g)].
With MuPAD up to version 2.5.3, an element of this domain is aligned vertically on its topmost row.
Starting from MuPAD 3.0.0, an element of this domain is centered vertically by default. Furthermore, you can choose the alignment style between Bottom, Center, Top, or set the baseline explicitly, as a number in the range [1..g::dom::height(g)]. Setting a baseline of has the same effect as choosing the style Bottom.
Internally, the first operand of an element of this domain is a list of strings of same lengths. The character of coordinate [x,y] is stored in the x-th character of the y-th string. The second operand describes the alignment style.
The call output::asciiArt(list) constructs a graphic by vertically stacking the strings in list, ragged left, from bottom to top (and not from top to bottom, in order to be consistent with the orientation of the y axis).
fromArray – boxed (or partially boxed) cell graphic from 2D array
output::asciiArt::fromArray(a, <separators>)
Parameters:
a, separators: |
2D arrays. |
Constructs a graphic made of vertically and horizontally aligned boxed cells filled with the initialized values of the array.
The optional separators argument allows for drawing partially boxed cells. Each entry of the optionnal array is a list of four booleans, corresponding to the four directions (north, east, south, west). A TRUE value means that there is a separator between the cell and the adjacent cell in that direction.
Currently, the values themselves are represented in 1D and not pretty printed.
width – width of a graphic
output::asciiArt::width(g)
Parameters:
g: |
A graphic. |
Returns the width of g in characters.
height – height of a graphic
output::asciiArt::height(g)
Parameters:
g: |
A graphic. |
Returns the height of g in characters.
alignment – vertical alignment
output::asciiArt::alignment(g)
Parameters:
g: |
A graphic. |
Returns the vertical alignment style or base line of g.
setAlignment – sets the vertical alignment
output::asciiArt::setAlignment(g, Bottom | Center | Top | baseline)
Parameters:
g: |
A graphic. |
baseline: |
An integer value for the vertical alignment. |
Returns a copy of g, with the given vertical alignment style or with the baseline set to baseline. If needed, the result is extended vertically so that its height is no less than its baseline.
flipx – horizontal flip
output::asciiArt::flipx(g)
Parameters:
g: |
A graphic. |
Returns a copy of g flipped horizontally.
flipy – vertical flip
output::asciiArt::flipy(g)
Parameters:
g: |
A graphic. |
Returns a copy of g flipped vertically.
We demonstrate some basic usage of this domain. Here is a little graphic:
tom := output::asciiArt([" \\_/ ", "| _ |", "|o o|", "//|\\\\", " ___"])
___
//|\\
|o o|
| _ |
\_/
The output is not yet quite perfect, but such a graphic can be included in a complex formula:
(2*tom + 1)/(x + tom^2)
___
//|\\
2 |o o| + 1
| _ |
\_/
-----------
___ 2
//|\\
x + |o o|
| _ |
\_/
We fetch some information on this graphic. This is its size:
[tom::dom::height(tom), tom::dom::width(tom)]
Here are some of its characters:
tom[1, 1], tom[3, 1], tom[1, 3], tom[2, 3]
Fetching a character out of bounds raises an error.
tom[6, 6]
Error: Out of range [output::asciiArt::_index]
The graphic can more or less be fliped around:
tom::dom::flipx(tom)
___
\\|//
|o o|
| _ |
/_\
tom::dom::flipy(tom)
\_/
| _ |
|o o|
//|\\
___
tom::dom::transpose(tom)
/_\
| _ |
|o o|
\\|//
___
It is time to do some drawing now:
tom[2, 3] := "v":
tom
___
//|\\
|v o|
| _ |
\_/
tom[3, 5] := tom[4, 6] := "/":
tom[4, 7] := "ooo": tom[5, 8] := tom[5, 6] := "o":
tom;
o
ooo
/o
_/_
//|\\
|v o|
| _ |
\_/
All of this does not look very serious, does it? Well, do not be misleaded. This hack is very handy for quick and simple preview of combinatorial structures. And, as usual with combinatorics, fun and seriousness are never very far away.
combinat::dyckWords::printPretty([1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0])
/\
/\ / \/\
/ \/\/\ /\/ \
/ \/ \
combinat::binaryTrees(([a, [b,[c], [d]], [e, [],[f]]]));
a
/ \
b e
/ \ \
c d f
combinat::partitions::printPretty([5, 3, 1])
+---+
| |
+---+---+---+
| | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
combinat::tableaux([[3], [1, 2, 4]])
+---+
| 3 |
+---+---+---+
| 1 | 2 | 4 |
+---+---+---+
combinat::ribbonsTableaux(
[[2,1,1],[[1],
[0],
[0,1,4,0,0],
[0,3,0,0,3],
[0,2,0,0,0,0],
[1,0,0,2,0,0]]])
+---+
| |
+ +
| |
+ +---+---+---+---+
| 1 | | 4 |
+---+ +---+---+---+---+
| | 3 | 3 |
+ +---+---+---+ +---+
| 1 | 2 | |
+---+---+---+---+---+---+---+
| 1 | 2 |
+---+---+---+---+---+---+
The constructor output::asciiArt::fromArray is handy to create graphics with boxed cells. Here is how to draw a ribbon:
t := array(1..3, 1..6,
(1, 1) = 1, (1, 2) = 3, (1, 3) = 5,
(2, 3) = 4, (2, 4) = 6,
(3, 4) = 2):
output::asciiArt::fromArray(t)
+---+---+---+
| 1 | 3 | 5 |
+---+---+---+---+
| 4 | 6 |
+---+---+
| 2 |
+---+
We now illustrate some options that allow to customize the produced asciiArt:
output::asciiArt::fromArray(t,
RowSeparator = "", Cross = "",
ColumnSeparator = "*", HorizontalPadding = "")
*1*3*5*
*4*6*
*2*
output::asciiArt::fromArray(t, RowSeparator = "", Cross = "", HorizontalPadding = "")
|1|3|5|
|4|6|
|2|
output::asciiArt::fromArray(t, RowSeparator = "", Cross = "")
| 1 | 3 | 5 |
| 4 | 6 |
| 2 |
output::asciiArt::fromArray(t, Compact)
|1|3|5|
|4|6|
|2|
output::asciiArt::fromArray(t, Packed)
135
46
2
The optional separators argument of output::asciiArt::fromArray allows for full control over the separators drawn between the cells:
A := array(1..4, 1..4,
(1, 1) = a, (1, 2) = b, (1, 3) = c, (1, 4) = d,
(2, 1) = b, (2, 2) = c, (2, 3) = d, (2, 4) = a,
(3, 1) = c, (3, 2) = d, (3, 3) = a, (3, 4) = b,
(4, 1) = d, (4, 2) = a, (4, 3) = b, (4, 4) = c):
Separations conditions are given by the following array:
separator := array(1..4, 1..4,
(1, 1) = [TRUE,FALSE,FALSE,TRUE] , (1, 2) = [TRUE,FALSE,TRUE,FALSE],
(1, 3) = [TRUE,FALSE,TRUE,FALSE] , (1, 4) = [TRUE,TRUE,FALSE,FALSE],
(2, 1) = [FALSE,TRUE,FALSE,TRUE] , (2, 2) = [TRUE,FALSE,FALSE,TRUE],
(2, 3) = [TRUE,TRUE,FALSE,FALSE] , (2, 4) = [FALSE,TRUE,FALSE,TRUE],
(3, 1) = [FALSE,TRUE,FALSE,TRUE] , (3, 2) = [FALSE,FALSE,TRUE,TRUE],
(3, 3) = [FALSE,TRUE,TRUE,FALSE] , (3, 4) = [FALSE,TRUE,FALSE,TRUE],
(4, 1) = [FALSE,FALSE,TRUE,TRUE] , (4, 2) = [TRUE,FALSE,TRUE,FALSE],
(4, 3) = [TRUE,FALSE,TRUE,FALSE] , (4, 4) = [FALSE,TRUE,TRUE,FALSE]):
output::asciiArt::fromArray(A, separator)
+---+---+---+---+
| a b c d |
+ +---+---+ +
| b | c d | a |
+ + + +
| c | d a | b |
+ +---+---+ +
| d a b c |
+---+---+---+---+
This can typically be used to draw so-called rigging configurations:
a := array(1..2, 1..3, (1,1) = 3, (1,2) = 1, (2,1)="", (2,2)= 2, (2,3)=5):
s := array(1..2, 1..3,
(1,1) = [TRUE,TRUE,FALSE,TRUE] , (1,2) = [FALSE,FALSE,TRUE,TRUE], (1,3) = [FALSE,FALSE,FALSE,FALSE],
(2,1) = [FALSE,FALSE,TRUE,TRUE] , (2,2) = [TRUE,TRUE,TRUE,FALSE] , (2,3) = [FALSE,FALSE,FALSE,TRUE]):
output::asciiArt::fromArray(a, s);
+---+
| 3 | 1
+ +---+
| 2 | 5
+---+---+