次のマクロの出力を変数に保存したいと思います。
\foreach \m in {1,...,9}{\csname h\m \endcsname};
私がやろうとしたこと:
\def\lkj{
\foreach \m in {1,...,9}{\csname h\m \endcsname};
}
マクロが生成した出力ではなく、マクロ自体が保存されるため、機能しません。
出力を変数内に格納する方法を見つけるのを手伝ってくれる人はいませんか?
私が達成しようとしていることの説明
1 最小限の動作例
\documentclass{standalone}
\usepackage{xargs,tikz}
\usetikzlibrary{decorations.markings,hobby}
\tikzset{
mark pos/.style args={#1(#2)}{
postaction={
decorate,
decoration={
markings,
mark=at position #1 with \coordinate (#2);
}
}
}
}
\newcommandx*\arccal[6][6]{%
\draw[#6,domain=#5] plot ({#1+#3*cos(\x)}, {#2+#4*sin(\x)});
}
\foreach \m in {1,...,9}{
\expandafter\xdef\csname h\m \endcsname{mark pos=0.\m(m\m),}
}
\def\lkj{
\foreach \m in {1,...,9}{\csname h\m \endcsname};
}
\begin{document}
\begin{tikzpicture}
\arccal{-2.8}{0}{0.6}{1.2}{270:90}[samples=50,ultra thick,
mark pos=0.05(w1),
mark pos=0.1(w2),
mark pos=0.15(w3),
mark pos=0.2(w4),
mark pos=0.25(w5),
mark pos=0.3(w6),
mark pos=0.35(w7),
mark pos=0.4(w8),
mark pos=0.45(w9),
mark pos=0.5(w10),
mark pos=0.55(w11),
mark pos=0.6(w12),
mark pos=0.65(w13),
mark pos=0.7(w14),
mark pos=0.75(w15),
mark pos=0.8(w16),
mark pos=0.85(w17),
mark pos=0.9(w18),
mark pos=0.95(w19),
];
\draw[ultra thick] plot[smooth] coordinates {(w19)(w18)(w17)(w16)(w15)(w14)(w13)(w12)(w11)(w10)(w9)(w8)(w7)(w6)(w5)(w4)(w3)(w2)(w1)};
\end{tikzpicture}
\end{document}
2 解説
「mark pos」という名前の tikz スタイルがあり、これは「plot」で作成された線に座標を配置するために使用されます。
さまざまなパターンで滑らかに管理/閉じる必要がある特定の半円形の図形を作成するために、「plot[smooth]」または「plot[smooth cycle]」を使用する特定のケースがあります。
次に、特定の方向に移動するための一連の座標を定義する必要があります。この場合は、円形/楕円形を形成する方程式を使用し、「mark pos」を使用して座標を設定します。
場合によっては、十分に均質な曲線を形成するためにかなりの数の座標を定義する必要があるため、各座標を手動で定義しなくても、これらをすばやく作成するために、「foreach」を使用してループを作成したいと考えました。
foreach マクロの出力を "\draw[x]" 内に配置する必要がありますが、raw マクロ自体ではそれができません。
ありがとう。
Qrrbrbirlbelでコメントした例
1 ケース1: Qrrbrbirlbelの助けを借りて今できること
\newcommandx*\arccalpath[6][6]{%
\path[#6,domain=#5] plot ({#1+#3*cos(\x)}, {#2+#4*sin(\x)});
}
\arccalpath{-3}{0}{0.9}{1.2}{90:-90}[samples=50,ultra thick,
mark positions={0.05}{z}];
\arccalpath{-2.8}{0}{0.6}{1.2}{270:90}[samples=50,ultra thick,
mark positions={0.05}{w}]
\draw[ultra thick] plot[smooth,samples at={19,...,1}] (z\x);
\draw[ultra thick] plot[smooth,samples at={19,...,1}] (w\x);
2 ケース 2: プロット座標にこれらすべてのポイント (z1、z2、z3...) を入力することなく、取得したいもの。
\newcommandx*\arccalpath[6][6]{%
\path[#6,domain=#5] plot ({#1+#3*cos(\x)}, {#2+#4*sin(\x)});
}
\arccalpath{-3}{0}{0.9}{1.2}{90:-90}[samples=50,ultra thick,
mark positions={0.05}{z}];
\arccalpath{-2.8}{0}{0.6}{1.2}{270:90}[samples=50,ultra thick,
mark positions={0.05}{w}]
\draw[ultra thick] plot[smooth cycle,samples at={19,...,1}] coordinates
{(w19)(w18)(w17)(w16)(w15)(w14)(w13)(w12)(w11)(w10)(w9)(w8)(w7)(w6)(w5)(w4)(w3)(w2)(w1)(z19)(z18)(z17)(z16)(z15)(z14)(z13)(z12)(z11)(z10)(z9)(z8)(z7)(z6)(z5)(z4)(z3)(z2)(z1)};
答え1
私なら別の方法でアプローチします。
一定の間隔で複数のマーキングを配置するには、mark=between positions … and … step … with …
。マニュアルでは、すべての説明が記載されています。詳細キーの値は/pgf/decoration/mark info/sequence number
増分カウンターを提供します。
さらに、TikZ パスで使用できるスタイルを提供します。arccal
このスタイルでは、TikZ 形式の中心と半径の 2 つの引数だけを使用します<x> and <y>
。
3 番目の TikZ 画像では、楕円弧をプロットではなく楕円弧として描画します。
最後の図でmarkings
はライブラリは使用せず、角度の異なる 2 つの円弧を描画するだけです。円弧の全長の一部だけ円弧を短くする必要がある場合、アプローチは少し複雑になります (全長は PGF/TikZ の装飾モジュールによってのみ提供され、簡単には抽出できません)。それでも、数十のマークを配置してそれらに線を描画するよりはましです。
もありますより良い方法中心の周りに円弧を描くことですが、それはあなたの質問とは関係ありません。
コード
\documentclass{standalone}
\usepackage{xargs,tikz}
\usetikzlibrary{decorations.markings}
\tikzset{
mark positions/.style 2 args={
postaction=decorate,
decoration={
name=markings, % PGFMath isn't precise, cheat with 1-0.001
mark=between positions #1 and 1-0.001 step #1 with \coordinate
(#2\pgfkeysvalueof{/pgf/decoration/mark info/sequence number});}}}
\newcommandx*\arccal[6][6]{%
\draw[#6,domain=#5] plot ({#1+#3*cos(\x)}, {#2+#4*sin(\x)});
}
\tikzset{arccal/.style n args=2{insert path={plot([shift={(#1)}]\x:#2)}}}
\begin{document}
\begin{tikzpicture}
\arccal{-2.8}{0}{0.6}{1.2}{270:90}[
samples=50, ultra thick,
mark positions={0.05}{w}
];
\draw[thick, green] plot[smooth, samples at={19, ..., 1}] (w\x);
\end{tikzpicture}
\begin{tikzpicture}
\draw[
ultra thick, samples=50, domain=270:90,
mark positions={0.05}{w}, arccal={-2.8, 0}{.6 and 1.2}];
\draw[thick, green] plot[smooth, samples at={19, ..., 1}] (w\x);
\end{tikzpicture}
\begin{tikzpicture}
\draw[ultra thick, shift={(-2.8, 0)}, mark positions={0.05}{w}]
(270:.6 and 1.2) arc[start angle=270, end angle=90, x radius=.6, y radius=1.2];
\draw[thick, green] plot[smooth, samples at={19, ..., 1}] (w\x);
\end{tikzpicture}
\begin{tikzpicture}
\draw[ultra thick, shift={(-2.8, 0)}]
(270:.6 and 1.2) arc[start angle=270, end angle= 90, x radius=.6, y radius=1.2];
\draw[thick, green, shift={(-2.8, 0)}]
(255:.6 and 1.2) arc[start angle=255, end angle=105, x radius=.6, y radius=1.2];
\end{tikzpicture}
\end{document}
出力
私の見解では、交差点間の円弧を結合したいのですね。
ここでは 3 つのアプローチを紹介します。いずれもintersections
ライブラリを使用して、円弧/半楕円を構成する 2 つのパスの交差点を見つけます。
最初のものは、ライブラリの構文を使用して、calc
別let … in
のセットの楕円の中心に対する交点の角度を計算しますarc
。m1
m2
座標は、バツキャンバス座標系における楕円の半径を、変換を自分で行わなくても取得できます。
2つ目はext.paths.arcto
私のライブラリを使用していますtikz-ext
パッケージ円弧を描くことができるにポイントの場合、角度は PGF/TikZ によって計算されます。
3 番目のソリューションではspath3
、他のパスとの交差点でパスを分割できるようにするライブラリを使用します。分割されたパスのどのコンポーネントを描画するかを指定するだけです。
ソリューション 1 と 2 の数学的評価はあまり正確ではないため、パスを閉じるときに厄介なアーティファクトが発生します。
spath3
これは、のキーを使用して修正するadjust and close
か、 を使用して非表示にすることができますline join=round
。
全体的に、私はこれらのarc to
アプローチを好む。
- この
calc
アプローチでは多くの手動計算が使用されるだけでなく、acos
関数が明確ではないため(1つの値に対して2つの角度)、調整と - この
spath3
ソリューションでは、コンポーネントを指定する必要がありますが、円弧は最大 4 つのベジェ曲線 (それぞれがコンポーネントに対応) から構成されるため、これは複雑になる可能性があります。
いずれにしても、以下のコードではすべての解決策が提示されています。また、私の答えarc starts=after moveto
中心の周りに円弧を描きやすくするためです。
コード
\documentclass[border=5pt]{standalone}
\usepackage{tikz}
%% https://tex.stackexchange.com/a/123189
\usepackage{etoolbox}
\makeatletter
\patchcmd{\tikz@arc@opt}{\xdef}{\tikz@arc@do\xdef}{}{}\let\tikz@arc@do\relax
\tikzset{arc starts/.cd,.is choice, at last point/.code=\let\tikz@arc@do\relax,after moveto/.code=\tikz@arc@do@\pgfpathmoveto,after lineto/.code=\tikz@arc@do@\pgfpathlineto}
\def\tikz@arc@do@#1{\def\tikz@arc@do{\tikz@@@parse@polar{\tikz@arc@do@@#1}(\tikz@s:\pgfkeysvalueof{/tikz/x radius} and \pgfkeysvalueof{/tikz/y radius})}}
\def\tikz@arc@do@@#1#2{#1{\pgfpointadd{#2}{\tikz@last@position@saved}}}
\makeatother
\usetikzlibrary{intersections} % solutions 1, 2, 3
\usetikzlibrary{
calc, % solution 1
ext.paths.arcto, % solution 2
spath3 % solutions (1, 2b,) 3
}
\tikzset{cycle/.style=/tikz/spath/adjust and close}
\begin{document}
%%% 1. calc (doing our own math)
\begin{tikzpicture}[
arc starts=after moveto,
e1/.style={x radius=.6, y radius=1.2},
e2/.style={x radius=.9, y radius=1.2},
label position=center, line join=round,
]
% the coordinate m1 and m2 are used to find the x radius in the canvas (w/ units)
\path[name path=e1] (-2.8, 0) coordinate (c1)
arc[start angle=90, delta angle= 180, e1] coordinate[midway] (m1);
\path[name path=e2] (-3.0, 0) coordinate(c2)
arc[start angle=90, delta angle=-180, e2] coordinate[midway] (m2);
\draw[
ultra thick, arc starts=at last point,
name intersections={of=e1 and e2}]
% work in the coordinate system of the first ellipse:
[shift=(c1), e1]
let \p0=(intersection-1), \p1=(m1), \n0={180-acos(\x0/\x1)} in
(intersection-1) arc[start angle=\n0, end angle=360-\n0]
% work in the coordinate system of the second ellipse:
[shift=(c2), e2]
let \p0=(intersection-2), \p1=(m2), \n0={-acos(\x0/\x1)} in
arc[start angle=\n0, end angle=-\n0]
[cycle];
\end{tikzpicture}
%%% 2a. arc to + round line join
\begin{tikzpicture}[
arc starts=after moveto, line join=round,
e1/.style={x radius=.6, y radius=1.2},
e2/.style={x radius=.9, y radius=1.2},
]
\path[name path=e1] (-2.8, 0) arc[start angle=90, delta angle= 180, e1];
\path[name path=e2] (-3.0, 0) arc[start angle=90, delta angle=-180, e2];
\draw[name intersections={of=e1 and e2}, ultra thick]
(intersection-1) arc to[/tikz/e1] (intersection-2)
arc to[/tikz/e2] (intersection-1) -- cycle;
\end{tikzpicture}
%%% 2b. arc to + spath3
\begin{tikzpicture}[
arc starts=after moveto,
e1/.style={x radius=.6, y radius=1.2},
e2/.style={x radius=.9, y radius=1.2},
]
\path[name path=e1] (-2.8, 0) arc[start angle=90, delta angle= 180, e1];
\path[name path=e2] (-3.0, 0) arc[start angle=90, delta angle=-180, e2];
\draw[name intersections={of=e1 and e2}, ultra thick]
(intersection-1) arc to[/tikz/e1] (intersection-2)
arc to[/tikz/e2] (intersection-1) [cycle];
\end{tikzpicture}
% 3. spath
\begin{tikzpicture}[
arc starts=after moveto,
e1/.style={x radius=.6, y radius=1.2},
e2/.style={x radius=.9, y radius=1.2},
label position=center,
]
\path[name path=e1] (-2.8, 0) coordinate (c1)
arc[start angle=90, delta angle= 180, e1];
\path[name path=e2] (-3.0, 0) coordinate(c2)
arc[start angle=90, delta angle=-180, e2];
\draw[ultra thick, spath/.cd,
split at intersections={e1}{e2},
remove components={e1}{2,4},
remove components={e2}{1,2,4},
use=e1, append reverse=e2,
] -- cycle;
\end{tikzpicture}
\end{document}