PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tikz: Nodes einkreisen



MC3330
21-08-2020, 15:32
Hallo,

ich würde gerne in einem Viereck an bestimmte Anzahl an Nodes (quasi)zufällig verteilen, ohne dass es zu Überlappungen kommt. Ich habe das ganze jetzt einigermaßen hinbekommen, indem ich sie in einem Gitter anordne und x- und y-Komponente jeweils einen zufälligen Wert addiere.

Als zweites würde ich es gerne hinbekommen, dass immer eine bestimmte Anzahl an Nodes farbig eingekreist wird.Ich habe es mit der Fit-Library einigermaßen hinbekommen, allerdings kommt es dabei zu Überschneidungen. Ich würde es gerne hinbekommen, dass es ungefähr so wie im Bild aussieht.

6289

Hat da vielleicht jemand eine Idee?
Viele Grüße
MC



Minimalbeispiel


\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{math,fit}

\begin{document}

\directlua{
r = 2
cx = {0+math.random(-r,r)/10,
1+math.random(-r,r)/10,
2+math.random(-r,r)/10,
3+math.random(-r,r)/10,
4+math.random(-r,r)/10,
0+math.random(-r,r)/10,
1+math.random(-r,r)/10,
2+math.random(-r,r)/10,
3+math.random(-r,r)/10,
4+math.random(-r,r)/10,
0+math.random(-r,r)/10,
1+math.random(-r,r)/10,
2+math.random(-r,r)/10,
3+math.random(-r,r)/10,
4+math.random(-r,r)/10}
cy = {0+math.random(-r,r)/10,
0-math.random(-r,r)/10,
0-math.random(-r,r)/10,
0-math.random(-r,r)/10,
0-math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-2+math.random(-r,r)/10,
-2+math.random(-r,r)/10,
-2+math.random(-r,r)/10,
-2+math.random(-r,r)/10,
-2+math.random(-r,r)/10}
fit={1,2,3,4,5,10,6,7,11,8,12,13,9,14,15}
}
\newpage
\begin{tikzpicture}
\draw[rounded corners = 5pt](-0.75,-3.5)--(4.75,-3.5)--(4.75,0.75)--(-0.75,0.75)--cycle;

\foreach \n in {1,...,15}{
\node (\n) at (\directlua{tex.print(cx[\n])},\directlua{tex.print(cy[\n])}){x};
}
\foreach \n in {1,4,7,10,13}{
\tikzmath{%//
\nz = int(\n+1);
\nd = int(\n+2);
}%\\
\node[draw=green, fit=(\directlua{tex.print(fit[\n])}) (\directlua{tex.print(fit[\n+1])})(\directlua{tex.print(fit[\n+2])}),inner sep=0mm](FIt2) {};
}



\end{tikzpicture}

\end{document}

rais
30-08-2020, 20:32
Eine grobe Idee wäre, die entsprechenden Punkte selbst einzukreisen


\documentclass{scrartcl}
\usepackage{tikz}
\usetikzlibrary{math,fit}
\newcounter{variant}
\newif\ifhinearmax
\newif\ifvinearmax
\newif\ifnearhorizontal
\newif\ifnearvertical
\newif\ifxiverynear
\newif\ifyiverynear
\newcommand*\surround[4][red]{%
% #1: Optionen für \draw
% #2--4: die Nodes
% Init:
\edef\LeftMost{#2}%
\edef\RightMost{#2}%
\edef\TopMost{#2}%
\edef\BotMost{#2}%
\edef\XMiddle{#2}%
\edef\YMiddle{#2}%
\edef\Xi{\directlua{tex.print(cx[#2])}}%
\edef\Xii{\directlua{tex.print(cx[#3])}}%
\edef\Xiii{\directlua{tex.print(cx[#4])}}%
\edef\Yi{\directlua{tex.print(cy[#2])}}%
\edef\Yii{\directlua{tex.print(cy[#3])}}%
\edef\Yiii{\directlua{tex.print(cy[#4])}}%
\edef\Xrm{\Xi}%
\edef\Xlm{\Xi}%
\edef\Ytm{\Yi}%
\edef\Ybm{\Yi}%
\edef\Xc{\Xi}%
\edef\Yc{\Yi}%
\hinearmaxfalse
\vinearmaxfalse
\xiverynearfalse
\yiverynearfalse
\nearhorizontalfalse
\nearverticalfalse
\edef\XYdmin{0.5}% minimaler Abstand für "nicht sehr nah"
\edef\r{3mm}% Radius für Bögen
% Suche Extrema:
% Test auf größtes X:
\pgfmathgreater{\Xii}{\Xi}%
\ifnum\pgfmathresult>0
\edef\RightMost{#3}%
\edef\Xrm{\Xii}%
\pgfmathgreater{\Xiii}{\Xii}%
\ifnum\pgfmathresult>0
\edef\RightMost{#4}%
\edef\Xrm{\Xiii}%
\fi
\else
\pgfmathgreater{\Xiii}{\Xi}%
\ifnum\pgfmathresult>0
\edef\RightMost{#4}%
\edef\Xrm{\Xiii}%
\fi
\fi
% Test auf kleinstes X:
\pgfmathless{\Xii}{\Xi}%
\ifnum\pgfmathresult>0
\edef\LeftMost{#3}%
\edef\Xlm{\Xii}%
\pgfmathless{\Xiii}{\Xii}%
\ifnum\pgfmathresult>0
\edef\LeftMost{#4}%
\edef\Xlm{\Xiii}%
\fi
\else
\pgfmathless{\Xiii}{\Xi}%
\ifnum\pgfmathresult>0
\edef\LeftMost{#4}%
\edef\Xlm{\Xiii}%
\fi
\fi
% Test auf größtes Y:
\pgfmathgreater{\Yii}{\Yi}%
\ifnum\pgfmathresult>0
\edef\TopMost{#3}%
\edef\Ytm{\Yii}%
\pgfmathgreater{\Yiii}{\Yii}%
\ifnum\pgfmathresult>0
\edef\TopMost{#4}%
\edef\Ytm{\Yiii}%
\fi
\else
\pgfmathgreater{\Yiii}{\Yi}%
\ifnum\pgfmathresult>0
\edef\TopMost{#4}%
\edef\Ytm{\Yiii}%
\fi
\fi
% Test auf kleinstes Y:
\pgfmathless{\Yii}{\Yi}%
\ifnum\pgfmathresult>0
\edef\BotMost{#3}%
\edef\Ybm{\Yii}%
\pgfmathless{\Yiii}{\Yii}%
\ifnum\pgfmathresult>0
\edef\BotMost{#4}%
\edef\Ybm{\Yiii}%
\fi
\else
\pgfmathless{\Yiii}{\Yi}%
\ifnum\pgfmathresult>0
\edef\BotMost{#4}%
\edef\Ybm{\Yiii}%
\fi
\fi
% Mittelpunkte x,y:
\pgfmathsubtract{\Xrm}{\Xlm}%
\let\dxmax\pgfmathresult
\pgfmathdivide{\dxmax}{2}%
\let\mytmp\pgfmathresult
\pgfmathadd{\Xlm}{\mytmp}%
\let\Xcenter\pgfmathresult
\pgfmathsubtract{\Ytm}{\Ybm}%
\let\dymax\pgfmathresult
\pgfmathdivide{\dymax}{2}%
\let\mytmp\pgfmathresult
\pgfmathadd{\Ybm}{\mytmp}%
\let\Ycenter\pgfmathresult
% InnenXc, Yc:
\ifx\Xlm\Xi
\ifx\Xrm\Xii
\edef\Xc{\Xiii}%
\edef\XMiddle{#4}%
\else
\edef\Xc{\Xii}%
\edef\XMiddle{#3}%
\fi
\else
\ifx\Xlm\Xii
\ifx\Xrm\Xi
\edef\Xc{\Xiii}%
\edef\XMiddle{#4}%
\fi% sonst \Xc = \Xi (vorbelegt)
\else
%\Xlm=\Xiii
\ifx\Xrm\Xi
\edef\Xc{\Xii}%
\edef\XMiddle{#3}%
\fi% sonst \Xc = \Xi
\fi
\fi
\ifx\Ytm\Yi
\ifx\Ybm\Yii
\edef\Yc{\Yiii}%
\edef\YMiddle{#4}%
\else
\edef\Yc{\Yii}%
\edef\YMiddle{#3}%
\fi
\else
\ifx\Ytm\Yii
\ifx\Ybm\Yi
\edef\Yc{\Yiii}%
\edef\YMiddle{#4}%
\fi% sonst \Yc = \Yi
\else
%\Ytm=\Yiii
\ifx\Ybm\Yi
\edef\Yc{\Yii}%
\edef\YMiddle{#3}%
\fi% sonst \Yc = \Yi
\fi
\fi
\typeout{+++ T: \TopMost (\Ytm), M: \YMiddle (\Yc), B: \BotMost (\Ybm)}%
\typeout{+++ L: \LeftMost (\Xlm), M: \XMiddle (\Xc), R: \RightMost (\Xrm) (#2/#3/#4)}%
% Test auf Ecke(n):
\setcounter{variant}{0}% init / noch kein Eckpunkt
\ifx\TopMost\LeftMost
\setcounter{variant}{1}% oben links
\fi
\ifx\TopMost\RightMost
\addtocounter{variant}{2}% oben rechts
\fi
\ifx\BotMost\LeftMost
\addtocounter{variant}{4}% unten links
\fi
\ifx\BotMost\RightMost
\addtocounter{variant}{8}% unten rechts
\fi
% Test auf Nähe (Xc dichter an Max oder Min?)
\pgfmathgreater{\Xc}{\Xcenter}%
\ifnum\pgfmathresult>0
\hinearmaxtrue
\pgfmathsubtract{\Xrm}{\Xc}%
\let\dximin\pgfmathresult
\else
\pgfmathsubtract{\Xc}{\Xlm}%
\let\dximin\pgfmathresult
\fi
\pgfmathgreater{\Yc}{\Ycenter}%
\ifnum\pgfmathresult>0
\vinearmaxtrue
\pgfmathsubtract{\Ytm}{\Yc}%
\let\dyimin\pgfmathresult
\else
\pgfmathsubtract{\Yc}{\Ybm}%
\let\dyimin\pgfmathresult
\fi
\pgfmathless{\dximin}{\XYdmin}%
\ifnum\pgfmathresult>0
\xiveryneartrue
\fi
\pgfmathless{\dyimin}{\XYdmin}%
\ifnum\pgfmathresult>0
\yiveryneartrue
\fi
\pgfmathless{\dxmax}{\XYdmin}%
\ifnum\pgfmathresult>0
\nearverticaltrue
\fi
\pgfmathless{\dymax}{\XYdmin}%
\ifnum\pgfmathresult>0
\nearhorizontaltrue
\fi
\typeout{+++ Variant \the\value{variant}}%
\typeout{X Abstand außen \dxmax, kleinster X Abstand innen \dximin}%
\typeout{Y Abstand außen \dymax, kleinster Y Abstand innen \dyimin}%
\ifcase\value{variant}% 0: gar kein Eckpunkt?
\typeout{Gar kein Eckpunkt?}%
\or %1: oben links, unten keine Ecke
\ifnearhorizontal
\draw[#1] (\LeftMost.south) arc [start angle=270, end angle=90, radius=\r]
-- (\XMiddle.north) -- (\RightMost.north)
arc[start angle=90, end angle =-90, radius=\r]
-- (\XMiddle.south) -- cycle;
\else
\draw[#1] (\LeftMost.south) arc[start angle=270, end angle=0, radius=\r] -- (\RightMost.north west) arc[start angle=135, end angle=-135, radius=\r]
-- (\XMiddle.east) arc[start angle=0, end angle=-225, radius=\r] -- cycle;
\fi
\or %2: oben rechts, unten keine Ecke
\or %3: oben links, oben rechts, unten keine Ecke
\or %4: oben keine Ecke, unten links
\or %5: oben links, unten links
\or %6: oben rechts, unten links
\or %7: oben links, oben rechts, unten links
\or %8: oben keine Ecke, unten rechts
\or %9: oben links, unten rechts
\or%10: oben rechts, unten rechts
\or%11: oben links, oben rechts, unten rechts
\or%12: oben keine Ecke, unten links, unten rechts
\or%13: oben links, unten links, unten rechts
\or%14: oben rechts, unten links, unten rechts
\or%15: oben links, oben rechts, unten links, unten rechts
\else%>=16:
\typeout{Unbekannte Variante (\the\value{variant})!}%
\fi
}
\begin{document}

\directlua{
r = 2
cx = {0+math.random(-r,r)/10,
1+math.random(-r,r)/10,
2+math.random(-r,r)/10,
3+math.random(-r,r)/10,
4+math.random(-r,r)/10,
0+math.random(-r,r)/10,
1+math.random(-r,r)/10,
2+math.random(-r,r)/10,
3+math.random(-r,r)/10,
4+math.random(-r,r)/10,
0+math.random(-r,r)/10,
1+math.random(-r,r)/10,
2+math.random(-r,r)/10,
3+math.random(-r,r)/10,
4+math.random(-r,r)/10}
cy = {0+math.random(-r,r)/10,
0-math.random(-r,r)/10,
0-math.random(-r,r)/10,
0-math.random(-r,r)/10,
0-math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-1+math.random(-r,r)/10,
-2+math.random(-r,r)/10,
-2+math.random(-r,r)/10,
-2+math.random(-r,r)/10,
-2+math.random(-r,r)/10,
-2+math.random(-r,r)/10}
fit={1,2,3,4,5,10,6,7,11,8,12,13,9,14,15}
}
% \newpage
\begin{tikzpicture}
\draw[rounded corners = 5pt](-0.75,-3.5)--(4.75,-3.5)--(4.75,0.75)--(-0.75,0.75)--cycle;

\foreach \n in {1,...,15}{
\node[circle, draw=red!20, inner sep=0pt, minimum size=6mm] (\n) at (\directlua{tex.print(cx[\n])},\directlua{tex.print(cy[\n])}){\n};% \n statt x damit ich leichter sehen kann welcher Node wo landet
}
\foreach \n in {1,4,7,10,13}{
% \tikzmath{%//
% \nz = int(\n+1);
% \nd = int(\n+2);
% }%\\
\node[draw=green, fit=(\directlua{tex.print(fit[\n])}) (\directlua{tex.print(fit[\n+1])})(\directlua{tex.print(fit[\n+2])}),inner sep=0pt](FIt2) {};
\surround[blue]{\directlua{tex.print(fit[\n])}}{\directlua{tex.print(fit[\n+1])}}{\directlua{tex.print(fit[\n+2])}}
}
\end{tikzpicture}

\end{document}

(nicht komplett; eine Idee halt)

VG

MC3330
31-08-2020, 15:52
Wow, vielen Dank. Das sieht ziemlich genau so aus, wie ich es gerne hätte. Danke für die große Mühe.