我是 LyX 用户,有一个小问题 -
我如何将一个仅由数字 {0,1} 组成的表格合并到我的文档中,表格单元格之间有边框,交叉点/角落处有小彩色圆圈,指示接触交叉点/角落的 1 的数量是奇数还是偶数。
谢谢!
答案1
更新!
我决定学习一点 lua,并将我的 Pythonic 解决方案转换为 LuaLaTeX。您可以直接跳到本节LuaLaTeX如果你对python不感兴趣。
原始答案
我会使用 tikz 绘制网格,在上面放置 1 和 0,然后绘制小圆圈。然而,计算每个圆圈的颜色仍然是一个问题。
虽然这肯定可以在纯乳胶中完成,但我认为这是一项艰巨的任务,因为 LaTeX 没有提供数据结构来保存此问题所需的二维数组。我认为 LuaTeX 解决方案(与 tikz 输出混合)是最好的方法,但我缺乏提供这种解决方案的技能。我很高兴看到一个。
同时,我编写了输出所需 tikz 代码的 Python 脚本。
数据:
data = [
[ 0, 1, 0, 0, 0, 1 ],
[ 1, 1, 1, 0, 1, 1 ],
[ 0, 1, 0, 1, 1, 0 ],
[ 0, 0, 1, 1, 0, 0 ],
[ 1, 0 ,0, 0, 1, 1 ]
]
结果:
代码(python,抱歉):
# Put here your data. You can add/remove rows and columns as required
# The code will self-adapt to the size of this matrix.
# Only requirement is that all rows should have the same length
data = [
[ 0, 1, 0, 0, 0, 1 ],
[ 1, 1, 1, 0, 1, 1 ],
[ 0, 1, 0, 1, 1, 0 ],
[ 0, 0, 1, 1, 0, 0 ],
[ 1, 0 ,0, 0, 1, 1 ]
]
# A little cheating...
# Next table will be equal to the one named "data", but padded
# with zeros at its contour
padded_data = []
width = len(data[0])+2
padded_data.append([0]*width) # First row of zeros
for row in data:
padded_data.append([0] + row + [0]) # Middle rows
padded_data.append([0]*width) # Last row of zeros
# This simplifies the implementation of the next fundamental function
def parity(y, x):
"""
This function computes the parity of a intersection/corner.
The intersection is located at the edge between rows and colums
so that (y,x) is the intersection of the line which separates
rows (y-1) and (y), and the line which separates columns (x-1)
and x, considering that column/row with index -1 is out of the matrix,
so that (0,0) represents the upper left corner of the table.
(in other words, the first cell of the table has the four corners
(0,0), (0,1), (1,1) and (1,0) in clockwise order).
The parity of an intersection/corner is defined as the parity
of the sum of the cells which have that corner. For intersections
"inside" the matrix, each one has four "touching" cells.
For intersections in the border of the matrix, each one has
two "touching" cells, except for the intersections at the border
of the matrix which have a single "touching" cell.
"""
# We use padded data instead of data to make easier the computations
s = padded_data[y][x] + padded_data[y][x+1] + padded_data[y+1][x] + padded_data[y+1][x+1]
return s%2
# Given the data matrix, compute parity matrix
parity_matrix = []
for y in range(len(data)+1):
row = []
for x in range(len(data[0])+1):
row.append(parity(y,x))
parity_matrix.append(row)
# All required data is available. The figure can be drawn
width=len(parity_matrix[0])
height=len(parity_matrix)
print r"\begin{tikzpicture}[y=-.5cm, x=.5cm]"
# Draw the grid
for y in range(height):
print r"\draw[lines] (0,%d) -- (%d,%d);" % (y, width-1, y)
for x in range(width):
print r"\draw[lines] (%d,0) -- (%d,%d);" % (x, x, height-1)
# Draw the coloured dots at the intersections
for y in range(height):
for x in range(width):
if parity_matrix[y][x] == 1:
style="odd"
else:
style="even"
print r"\fill[%s] (%d,%d) circle(3pt);" % (style, x, y)
# Put the numbers at the cells
for y in range(len(data)):
for x in range(len(data[0])):
print r"\node[digit] at (%f, %f) {%d};" % (x+0.5, y+0.5, data[y][x])
# That's it!
print r"\end{tikzpicture}"
Latex 文档:
\documentclass{article}
\usepackage{tikz}
\tikzset{
even/.style = {fill=green, opacity=0.5},
odd/.style = {fill=red, opacity=0.5},
digit/.style = {font=\ttfamily},
lines/.style = {black}
}
\begin{document}
\input mygrid.tex
\end{document}
如何:
例如,将 Python 代码另存为compute-grid.py
,将.tex
代码另存为document.tex
。在终端执行:
$ python compute_grid.py > mygrid.tex
$ pdflatex document.tex
LuaLaTeX
上面的 Python 代码可以轻松移植到 Lua(尽管数组索引从 1 开始而不是从 0 开始让我有些头疼)。由于 LuaLaTeX 可以执行嵌入在 Latex 文档中的 Lua 代码,因此以下解决方案可以在单个文件中完全编码,但我更喜欢将其分成两个文件,以便“整理”主文档。
这是主要文件:
\documentclass{article}
\usepackage{fontspec}
\usepackage{luacode}
\usepackage{tikz}
\tikzset{
digit/.style = {font=\ttfamily},
line/.style = {black},
even/.style = {fill=green, opacity=.5},
odd/.style = {fill=red, opacity=.5}
}
\luaexec{ dofile("luafunctions.lua") }
\def\DrawGrid#1{ \luaexec{ data = {#1}; draw_grid(data) } }
\begin{document}
\begin{tikzpicture}[x=0.5cm, y=-0.5cm]
\DrawGrid{
{ 0, 1, 0, 0, 0, 1 },
{ 1, 1, 1, 0, 1, 1 },
{ 0, 1, 0, 1, 1, 0 },
{ 0, 0, 1, 1, 0, 0 },
{ 1, 0 ,0, 0, 1, 1 }
}
\end{tikzpicture}
\end{document}
luafunctions.lua
这是文件的内容:
function pad_array(data)
-- Create the padded array
padded = {}
width = #data[1] + 2
height = #data + 2
rowzeros = {}
for i=1,width,1 do
rowzeros[i] = 0
end
padded[1] = rowzeros
padded[height] = rowzeros
for i,v in ipairs(data) do
row = {}
row[1] = 0
for j,n in ipairs(v) do
row[j+1] = n
end
row[width] = 0
padded[i+1] = row
end
return padded
end
function parity(data, y, x)
-- Returns the parity of the intersection (y,x)
return(data[y][x] + data[y+1][x+1] + data[y+1][x] + data[y][x+1])%2
end
function compute_parity_matrix(data)
-- Computes the parity matrix
m = {}
padded = pad_array(data)
width = #padded[1]
height = #padded
for y=1,height-1,1 do
m[y]={}
for x=1,width-1,1 do
m[y][x] = parity(padded, y, x)
end
end
return m
end
function draw_grid(d)
-- Print the numbers
for y,v in ipairs(d) do
for x,n in ipairs(v) do
tex.print(string.format("\\node[digit] at (%f,%f) {%d};", x-.5, y-.5, n))
end
end
-- Draw the grid around
width = #d[1]
height = #d
for y=0,height,1 do
tex.print(string.format("\\draw[line] (0,%d) -- (%d,%d);", y, width, y))
end
for x=0,width,1 do
tex.print(string.format("\\draw[line] (%d,0) -- (%d,%d);", x,x,height))
end
-- compute parity matrix
pm = compute_parity_matrix(d)
-- use it to draw dots at intersections
for y, row in ipairs(pm) do
for x, parity in ipairs(row) do
if parity==1 then
style = "odd"
else
style = "even"
end
tex.print(string.format("\\fill[%s] (%d,%d) circle(3pt);", style, x-1, y-1))
end
end
end
使用命令编译主文档后lualatex
,您将获得pdf
与 Python 版本相同的结果: