贝塞尔控制的松散性。或者如何在圆形对称的 tikz 绘图中弯曲(不向左弯曲等)

贝塞尔控制的松散性。或者如何在圆形对称的 tikz 绘图中弯曲(不向左弯曲等)

如果我想画一个具有圆形对称性的东西,例如用圆弧连接一对点,如图所示,只有两个圆弧,我面临的问题是无法使用边缘弯曲。这是因为它意味着选择(bend left或右,或...),这会破坏对称性。

我想将边缘弯曲到圆心,但圆弧向圆心弯曲太多(蓝色圆弧)。我可以通过添加坐标(红色圆弧)等方式进行纠正。没有选项可以告诉controls ..不要弯曲太多吗?

底部还有另一张图片,显示了我不想要的东西(如果我使用 就会发生这种情况bend left)。我希望所有弧线都被拉到中心。我无法通过在有限的时间内手动重新排序大列表来修复。

在此处输入图片描述

\documentclass{standalone} 
\usepackage{tikz}

\usepackage{ifthen}


\usepackage{pgfplots} 
\usetikzlibrary{calc}

\begin{document}


\begin{tikzpicture}[scale=1]


\coordinate (O) at (0,0);
\draw (O)  circle (4);
%  
 \foreach \i in {1,2,...,8} {

 \node[draw,fill=white,circle] (p\i) at ($(O)+(360*\i/8:4)$)  {\i};
   }

\draw [blue] (p1) .. controls (O) ..  (p3); 
\draw [red] (p1) .. controls  ($(O)+.3*(p2)$)  ..  (p3); 

\end{tikzpicture}

\end{document}

通过使用,比如说

\path [violet, bend left=30, looseness=1.3]
(p1) edge (p2)
(p3) edge (p4)
(p5) edge (p6)
% since I cannot order points, I'll have 
% pairings like the next one:
(p8) edge (p7)
;

这就是我所说的对称性破坏:其中一个边缘向另一侧弯曲,而不是向中心弯曲。我无法重新排序数据以反转弯曲侧。

在此处输入图片描述

答案1

对于你的问题“难道没有选项可以告诉控制器...不要弯曲那么多吗?”,我想答案是. 这是因为bend leftlooseness影响 Ti为您创建控制点。如果您自己选择控制点,则可以绕过该逻辑。然后曲线的路径由数学公式确定,因此为了使其看起来不同,您必须选择不同的控件。

但是,您可以使用坐标系使中间控制点的计算变得更容易一些barycentric cs(另请参阅 pgfmanual 13.2.2 重心系统)。这样您就不需要知道起点和终点之间的坐标((p2)在您的示例中)。

绿线是示例图中所有可能的连接,循环除外。红线/蓝线显示当您改变坐标的影响时重心坐标系的工作方式(O)

示例输出

\documentclass{article} 
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}[scale=1]

\coordinate (O) at (0,0);
\draw (O) circle (4);

\foreach \i in {1,2,...,8} {
    \node[draw,fill=white,circle] (p\i) at (360*\i/8:4)  {\i};
}

% Demonstrate influence of O=\looseness in barycentric cs on (p1)--(p3)
\foreach[evaluate={\col={15*\looseness}}] \looseness in {0, 0.25, 0.5, 0.75, 1, 2, ..., 6} {
    \draw [color=blue!\col!red] (p1) .. controls (barycentric cs:p1=0.5,p3=0.5,O=\looseness) ..  (p3); 
}

% Draw all possible edges 
\tikzstyle{every edge}=[
    draw, green,
    to path={
        .. controls (barycentric cs:\tikztostart=0.5,\tikztotarget=0.5,O=0.3) ..
        (\tikztotarget) \tikztonodes
    },
]
\foreach \i in {1, ..., 8}{
    \foreach \j in {1, ..., 8}{
        \ifnum\i=\j\else
            \draw [green] (p\i) edge (p\j); 
        \fi
    }
}

\end{tikzpicture}
\end{document}

答案2

有了bend left,你应该能够得到你想要的(除非我完全误解了你的要求)......但你必须注意坐标的顺序。

\documentclass{standalone} 
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}


\begin{tikzpicture}[scale=1]


\coordinate (O) at (0,0);
\draw (O)  circle (4);
%  
 \foreach \i in {1,2,...,8} {

 \node[draw,fill=white,circle] (p\i) at ($(O)+(360*\i/8:4)$)  {\i};
   }
\foreach \i/\j in {1/3,2/4,3/5,4/6,5/7,6/8,7/1,8/2}{
\draw [blue] (p\i) .. controls (O) ..  (p\j); 
\draw [red] (p\i) .. controls  ($(O)+.3*(p2)$)  ..  (p\j); 
\draw [green,bend left,looseness=1.5] (p\i) edge (p\j); 
}
\end{tikzpicture}

\end{document}

在此处输入图片描述

编辑一种采用数字排序的提议,以便实际绘图总是按照增加的节点数进行。

\documentclass{standalone} 
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}


\begin{tikzpicture}[scale=1]


\coordinate (O) at (0,0);
\draw (O)  circle (4);
%  
 \foreach \i in {1,2,...,8} {

 \node[draw,fill=white,circle] (p\i) at ($(O)+(360*\i/8:4)$)  {\i};
   }
\foreach \ii/\jj [
    evaluate={\ii as \i using ifthenelse(\jj<\ii,int(\jj),int(\ii))},
    evaluate={\jj as \j using ifthenelse(\jj<\ii,int(\ii),int(\jj))},
] in {1/2,3/4,5/6,7/8,7/6}{
\draw [blue] (p\i) .. controls (O) ..  (p\j); 
\draw [red] (p\i) .. controls  ($(O)+.3*(p2)$)  ..  (p\j); 
\draw [green,bend left,looseness=1] (p\i) edge (p\j); 
}
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容