Obtenga el resultado de foreach en lugar del propio foreach

Obtenga el resultado de foreach en lugar del propio foreach

Quiero obtener el resultado de la siguiente macro almacenada en una variable:

\foreach \m in {1,...,9}{\csname h\m \endcsname};

Intenté hacer:

\def\lkj{
  \foreach \m in {1,...,9}{\csname h\m \endcsname};
}

No funciona debido a que almacena la macro en sí, no el resultado que produce.

¿Alguien podría ayudarme a descubrir cómo hacer que el resultado se almacene dentro de una variable?


Explicación de lo que estoy tratando de lograr.

1 ejemplo de trabajo mínimo

\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 comentario

Tengo un estilo tikz llamado "mark pos", que sirve para colocar coordenadas a través de líneas creadas con "plot".

Hay casos específicos en los que uso "trazar[suave]" o "trazar[ciclo suave]" para crear formas que tienen formas semicirculares específicas que deben gestionarse/cerrarse suavemente en una variedad de patrones.

Luego tengo que definir una serie de coordenadas para que vaya de la manera que quiero, en este caso uso una ecuación que forma formas circulares/elípticas y uso la "marca pos" para establecer las coordenadas.

En algunos casos tengo que definir una cantidad considerable de coordenadas para que forme una curva lo suficientemente homogénea, por eso quise crear un bucle con "foreach" para hacerlas rápidamente sin tener que definir cada una a mano.

Necesito colocar la salida de la macro foreach dentro de "\draw[x]", no puedo hacerlo con la macro sin formato.


Gracias.


Ejemplificación que comenté con Qrrbrbirlbel

1 Caso uno: Lo que puedo conseguir ahora con la ayuda de 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);

Produce: ingrese la descripción de la imagen aquí

2 Caso dos: Lo que pretendo obtener, pero sin tener que escribir todos estos puntos (z1, z2, z3...) en las coordenadas del gráfico.

\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)};

Produce: ingrese la descripción de la imagen aquí

Respuesta1

Yo abordaría esto de manera diferente.

Se pueden colocar múltiples marcas en una separación fija con elmark=between positions … and … step … with … sintaxis. El manual explica todo.los detalles. El valor de la /pgf/decoration/mark info/sequence numberclave proporciona un contador incremental.


Además, proporcionaré un arccalestilo que puede utilizar en una ruta TikZ que solo usa dos argumentos: el centro y los radios en formato TikZ <x> and <y>.

La tercera imagen de TikZ dibuja el arco elíptico como un arco elíptico en lugar de una trama.

La última imagen no usa la markingsbiblioteca sino que simplemente dibuja dos arcos, la segunda con ángulos diferentes. Si realmente necesita que los arcos se acorten en una cantidad parcial de la longitud total del arco, el enfoque es un poco más complicado (la longitud total solo la proporciona el módulo de decoración de PGF/TikZ y no es fácilmente extraible) pero Aún mejor que colocar docenas de marcas y trazar una línea a través de ellas.


También haymejores manerasdibujar arcos alrededor de un centro, pero eso no es relevante para su pregunta.

Código

\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}

Producción

ingrese la descripción de la imagen aquí


A mi modo de ver, quieres combinar arcos entre las intersecciones.

Aquí hay tres enfoques, todos usan la intersectionsbiblioteca para encontrar la intersección entre los dos caminos que forman los arcos/semielipsis.

El primero utiliza la sintaxis calcde la biblioteca let … inpara calcular el ángulo de las intersecciones con los centros de la elipse para otro conjunto de arcs. el m1ym2 se utilizan para poder obtener laXradio de las elipses en el sistema de coordenadas del lienzo sin tener que hacer las transformaciones nosotros mismos.

El segundo utiliza elext.paths.arcto biblioteca de mitikz-extpaqueteque permite dibujar un arcoaun punto, los ángulos serán calculados por PGF/TikZ.

La tercera solución utiliza la spath3biblioteca que permite dividir caminos en las intersecciones con otros caminos. Sólo necesitamos especificar qué componentes de las rutas divididas se dibujarán.


Dado que las evaluaciones matemáticas de las soluciones 1 y 2 no son muy precisas, obtendrás artefactos molestos al cerrar las rutas:
ingrese la descripción de la imagen aquí

Esto se puede solucionar usando spath3la adjust and closeclave u ocultar usando line join=round.

En general, prefiero los arc toenfoques porque

  • el calcenfoque utiliza muchos cálculos manuales, pero también porque la acosfunción no es inequívoca (dos ángulos para un valor) y esto necesitará ajustes y
  • la spath3solución necesita que usted especifique los componentes, lo que puede resultar complicado porque los arcos se construyen a partir de hasta cuatro curvas de Bézier (cada una de las cuales corresponde a un componente).

De cualquier manera, en el código siguiente se presentan todas las soluciones. yo también estoy usandomi respuestaEs arc starts=after movetopara facilitar el dibujo de arcos alrededor de un centro.

Código

\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}

Producción

ingrese la descripción de la imagen aquí

información relacionada