我希望获得像这篇文章一样的最终结果: 使用 TikZ 制作螺旋状文本
但我遇到了两个问题
-
- 该解决方案不适用于希伯来语文本
-
- 它不适用于长段文本,甚至拉丁文本(我有超过 1000 个单词,我正在考虑使用小字体)
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.text}
\usepackage{fontspec}
\usepackage{polyglossia}
\usepackage{ebgaramond}
\setdefaultlanguage{italian}
\setotherlanguage{hebrew}
\newfontfamily{\hebrewfont}{New Peninim MT}
\begin{document}
\begin{tikzpicture}[
decoration={
reverse path,
text effects along path,
text={\texthebrew{מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן. רבי אליעזר אומר, בין תכלת לכרתי. וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות. הקורא מכאן ואילך לא הפסיד, כאדם הקורא בתורה
}},
text effects/.cd,
text along path,
character count=\i, character total=\n,
characters={scale=1-\i/\n}
}
]
\draw [decorate] (0,0)
\foreach \i [evaluate={\r=(\i/2000)^2;}] in {0,5,...,2880}{ -- (\i:\r)};
\end{tikzpicture}
\end{document}
答案1
我不确定您示例中的问题是什么原因造成的,但也许您会喜欢另一种方法。您可以为文本螺旋定义自己的命令,例如\textspiral
,它需要 3 个参数,第一个是可选的星号,它将确定螺旋的方向,第二个是可选的键值列表,其中包含三个可能的键,比例(默认值为 1)、半径(缩放前)和循环 - 螺旋的圈数(默认值为 6),最后是文本。
\documentclass{article}
\usepackage{polyglossia}
\usepackage{ebgaramond}
\setdefaultlanguage{italian}
\setotherlanguage{hebrew}
\newfontfamily\hebrewfont{David CLM}[Script=Hebrew]
%%%%%%%%%%%%%%%%%%%%%%%%%
\directlua{%
function haim_text_spirale(star, scale, length, loops, str, total, index)
local angle = loops*2*3.14159265*(index/total)
local scale = star and scale*index/total or scale*(1/total + 1 - index/total)
tex.sprint('\\pdfextension save\\pdfextension setmatrix {',
string.format('\csstring\%.4f',scale) .. " "
.. "0" .. " " .. "0" .. " "
.. string.format('\csstring\%.4f',scale),
'}', '\\pdfextension setmatrix {',
string.format('\csstring\%.4f',math.cos(angle)) .. " "
.. string.format('\csstring\%.4f',math.sin(angle)) .. " "
.. string.format('\csstring\%.4f',-math.sin(angle)) .. " "
.. string.format('\csstring\%.4f',math.cos(angle)), '}',
'\\rlap{\\hbox to' .. length .. '{\\hss',
'\\pdfextension setmatrix { 0 1 -1 0 }\\rlap{' .. str .. '}}}',
'\\pdfextension restore')
end
}
\newlength\haimspiralradius
\newcount\haimspiralloops
\DeclareKeys[haim/spiral]
{
radius.code = \setlength\haimspiralradius{#1},
radius.initial:n = 3cm,
loops.code = {\haimspiralloops=#1},
loops.initial:n = 6,
scale.code = \def\haimspiralscale{#1},
scale.initial:n = 1
}
\NewDocumentCommand\textspiral { s O{} m }
{%
\leavevmode
\bgroup
\SetKeys[haim/spiral]{#2}%
\setbox0=\hbox to\dimexpr \haimspiralscale\dimexpr
\haimspiralradius*2+\baselineskip\relax\relax{\hss
\directlua{%
local str = '#3'
local index = 0
local total = utf8.len(str)
for _, c in utf8.codes(str) do
index = index + 1
haim_text_spirale(\IfBooleanTF{#1}{true}{false},
\haimspiralscale, "\the\haimspiralradius",
\the\haimspiralloops, utf8.char(c), total, index)
end
}%
\hss}%
\ht0=\dimexpr\haimspiralscale\dimexpr\haimspiralradius+\baselineskip\relax\relax
\dp0=\dimexpr\haimspiralscale\dimexpr\haimspiralradius+\baselineskip\relax\relax
\box0
\egroup
}
%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\selectlanguage{hebrew}
\textspiral{%
מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן.
רבי אליעזר אומר, בין תכלת לכרתי.
וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות.
מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן.
רבי אליעזר אומר, בין תכלת לכרתי.
וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות.}
\textspiral*[scale = 1.75,
radius = 2cm,
loops = 5]{%
מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן.
רבי אליעזר אומר, בין תכלת לכרתי.
וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות.
מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן.
רבי אליעזר אומר, בין תכלת לכרתי.
וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות.}
\end{document}
或者如果你喜欢更高级的语法
\documentclass{article}
\usepackage{polyglossia}
\usepackage{ebgaramond}
\setdefaultlanguage{italian}
\setotherlanguage{hebrew}
\newfontfamily\hebrewfont{David CLM}[Script=Hebrew]
%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOn
\tl_new:N \l__haim_spiral_tl
\skip_const:Nn \c_haim_spiral_hss_skip { 0pt plus 1fil minus 1fil }
\box_new:N \l__haim_spiral_box
\int_new:N \l__haim_spiral_index_int
\int_new:N \l__haim_spiral_total_int
\cs_new_protected:Npn \haim_spiral_set_matrix:n #1
{
\pdfextension setmatrix { #1 }
}
\cs_new_protected:Npn \haim_spiral_save_state:
{
\pdfextension save \scan_stop:
}
\cs_new_protected:Npn \haim_spiral_restore_state:
{
\pdfextension restore \scan_stop:
}
\keys_define:nn { haim / spirale }
{
radius.dim_set:N = \l__haim_spirale_radius_dim,
radius.initial:n = 3cm,
loops.int_set:N = \l__haim_spirale_loops_int,
loops.initial:n = 6,
scale.tl_set:N = \l__haim_spirale_scale_tl,
scale.initial:n = 1
}
\NewDocumentCommand \textspiral { s O{} m }
{
\mode_leave_vertical:
\group_begin:
\keys_set:nn { haim / spirale } { #2 }
\tl_set:Nn \l__haim_spiral_tl { #3 }
\regex_replace_all:nnN { \ } { { \ } } \l__haim_spiral_tl
\int_set:Nn \l__haim_spiral_total_int { \tl_count:N \l__haim_spiral_tl }
\int_set:Nn \l__haim_spiral_index_int { 1 }
\hbox_set_to_wd:Nnn \l__haim_spiral_box { \l__haim_spirale_radius_dim
* \l__haim_spirale_scale_tl
* 2 + \baselineskip
* \l__haim_spirale_scale_tl }
{
\skip_horizontal:N \c_haim_spiral_hss_skip
\tl_map_inline:Nn \l__haim_spiral_tl
{
\haim_spiral_save_state:
\haim_spiral_set_matrix:n
{
\lua_now:e
{
local~ total = \int_use:N \l__haim_spiral_total_int \c_space_tl
local~ index = \int_use:N \l__haim_spiral_index_int \c_space_tl
tex.print
(
string.format('\csstring\%.4f',\l__haim_spirale_scale_tl
* (\IfBooleanF{#1}{1/total+1-}index/total)) .. "~"
.. "0" .. "~"
.. "0" .. "~"
.. string.format('\csstring\%.4f',\l__haim_spirale_scale_tl
* (\IfBooleanF{#1}{1/total+1-}index/total))
)
}
}
\haim_spiral_set_matrix:n
{
\lua_now:e
{
local~ total = \int_use:N \l__haim_spiral_total_int \c_space_tl
local~ index = \int_use:N \l__haim_spiral_index_int \c_space_tl
local~ angle = \int_use:N \l__haim_spirale_loops_int
*2*3.14159265*index/total \c_space_tl
tex.print
(
string.format('\csstring\%.4f',math.cos(angle)) .. "~"
.. string.format('\csstring\%.4f',math.sin(angle)) .. "~"
.. string.format('\csstring\%.4f',-math.sin(angle)) .. "~"
.. string.format('\csstring\%.4f',math.cos(angle))
)
}
}
\hbox_overlap_right:n
{
\hbox_to_wd:nn { \l__haim_spirale_radius_dim }
{
\skip_horizontal:N \c_haim_spiral_hss_skip
\haim_spiral_set_matrix:n { 0~ 1~ -1~ 0 }
\hbox_overlap_right:n { ##1 }
}
}
\haim_spiral_restore_state:
\int_incr:N \l__haim_spiral_index_int
}
\skip_horizontal:N \c_haim_spiral_hss_skip
}
\box_set_dp:Nn \l__haim_spiral_box { \l__haim_spirale_radius_dim
* \l__haim_spirale_scale_tl
+ \baselineskip }
\box_set_ht:Nn \l__haim_spiral_box { \l__haim_spirale_radius_dim
* \l__haim_spirale_scale_tl
+ \baselineskip }
\box_use:N \l__haim_spiral_box
\group_end:
}
\ExplSyntaxOff
%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\selectlanguage{hebrew}
\textspiral{%
מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן.
רבי אליעזר אומר, בין תכלת לכרתי.
וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות.
מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן.
רבי אליעזר אומר, בין תכלת לכרתי.
וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות.}
\textspiral*[scale = 7/4,
radius = 2cm,
loops = 5]{%
מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן.
רבי אליעזר אומר, בין תכלת לכרתי.
וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות.
מאימתי קורין את שמע בשחרית. משיכיר בין תכלת ללבן.
רבי אליעזר אומר, בין תכלת לכרתי.
וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות.}
\end{document}
答案2
我没有测试过长字符串,但我认为您可能会遇到由于数字过大而导致的问题,因为您使用字符串的长度进行了一些计算。另外,我认为您需要characters
通过将字符数增加 1 来调整输入的公式。
有关 Ti 如何获取更多信息钾Z 精确处理文本修饰参考手册,但最重要的是,它一次处理一个字符,这意味着您不能使用\texthebrew
该选项的值text
。此外,Ti钾Z 不会从右到左处理文本,但您可以使用以下text effects/reverse text
命令反转字符的顺序:
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{decorations.text}
\usepackage{fontspec}
\usepackage{polyglossia}
\setdefaultlanguage{italian}
\setotherlanguage{hebrew}
\newfontfamily{\hebrewfont}{DejaVu Sans}
\begin{document}
\begin{tikzpicture}[
decoration={
reverse path,
text effects along path,
text={קורין את שמע בשחרית. משיכיר בין תכלת ללבן. רבי אליעזר אומר, בין תכלת לכרתי. וגומרה עד הנץ החמה. רבי יהושע אומר, עד שלש שעות, שכן דרך בני מלכים לעמד בשלש שעות. הקורא מכאן ואילך לא הפסיד, כאדם הקורא בתורה},
text effects/.cd,
reverse text,
text along path,
character count=\i, character total=\n,
characters={scale=1-\i/(\n+1)
}
}
]
\hebrewfont
\draw[decorate] (0,0)
\foreach \i [evaluate={\r=(\i/2000)^2;}] in {0,5,...,2880}{ -- (\i:\r)};
\end{tikzpicture}
\end{document}