我有一个半矩形和一个可能相交的圆。圆首先位于矩形上方很远的位置,然后向下移动直到与矩形相交甚至穿过矩形。我感兴趣的是找到从两条路径的交点创建的路径。到目前为止,感谢 Heiko Oberiek,我知道如何为特殊情况生成新路径。我希望能够使用条件语句来确定这两个形状是否相交,如果相交,则交点的位置在哪里,最后通过减去这两个形状来生成新路径。这是我用于创建这两个形状的代码:
\documentclass{standalone}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{graphicx}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro\minX{2}
\pgfmathsetmacro\maxX{10}
\pgfmathsetmacro\minY{4}
\pgfmathsetmacro\maxY{10}
\pgfmathsetmacro\CX{11}
\pgfmathsetmacro\CY{12}
\pgfmathsetmacro\CR{2}
\pgfmathsetmacro\Roundness{0.2}
\begin{scope} [local bounding box=BoxWest]
\def\pathone{(.5*\maxX + .5*\minX,\maxY)
-- (-\Roundness + \maxX,\maxY)
arc (90:0:\Roundness)
-- (\maxX,\minY +\Roundness)
arc (360:270:\Roundness)
-- (.5*\maxX+ .5*\minX,\minY )}
\path [name path=pathone, draw=green] \pathone;
\path [name path=pathtwo, draw=blue](\CX,\CY)
circle (\CR);
\end{scope}
\end{tikzpicture}
\end{document}
等等。这是我的代码,只有当圆与半矩形在垂直线上相交时才有效(在两个 TikZ 路径的交点处相减):
\begin{tikzpicture}[x=10pt, y=10pt]
\pgfmathsetmacro\minX{2}
\pgfmathsetmacro\maxX{10}
\pgfmathsetmacro\minY{4}
\pgfmathsetmacro\maxY{10}
\pgfmathsetmacro\CX{11}
\pgfmathsetmacro\CY{7}
\pgfmathsetmacro\CR{3}
\pgfmathsetmacro\Roundness{0.2}
\pgfmathsetmacro\OneWestX{.5*\maxX + .5*\minX}
\pgfmathsetmacro\OneEastX{\maxX}
\pgfmathsetmacro\OneNorthY{\maxY}
\pgfmathsetmacro\OneSouthY{\minY}
\pgfmathsetmacro\DiffX{\CX-\OneEastX}
\pgfmathsetmacro\DiffY{sqrt(\CR * \CR - \DiffX * \DiffX)}
\pgfmathsetmacro\DiffAngle{acos(\DiffX/\CR)}
\def\paththree{
(\OneWestX, \OneNorthY)
-- (\OneEastX, \OneNorthY)
-- (\OneEastX, \CY + \DiffY) % North intersection point
arc (180 - \DiffAngle:180 + \DiffAngle: \CR)
-- (\OneEastX, \OneSouthY)
-- (\OneWestX, \OneSouthY)}
\draw \paththree;
\end{tikzpicture}
有人能帮我将这个解决方案推广到圆相对于半矩形的任何位置以及任何半径吗?
答案1
这是一个建议。
\documentclass{article}
\usepackage{tikz,pgfplots}
\pgfplotsset{compat=1.15}
\usetikzlibrary{intersections,fillbetween}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro\minX{2}
\pgfmathsetmacro\maxX{10}
\pgfmathsetmacro\minY{4}
\pgfmathsetmacro\maxY{10}
\pgfmathsetmacro\CX{11}
\pgfmathsetmacro\CY{12}
\pgfmathsetmacro\CR{2}
\pgfmathsetmacro\Roundness{0.2}
\begin{scope} [local bounding box=BoxWest]
\def\pathone{(.5*\maxX + .5*\minX,\maxY)
-- (-\Roundness + \maxX,\maxY)
arc (90:0:\Roundness)
-- (\maxX,\minY +\Roundness)
arc (360:270:\Roundness)
-- (.5*\maxX+ .5*\minX,\minY )}
\path [name path global=pathone, draw=green] \pathone;
\path [name path global=pathtwo, draw=blue](\CX,\CY)
circle (\CR);
\path [name intersections={of=pathone and pathtwo,total=\tot}]
\pgfextra{\pgfmathsetmacro{\NonTriv}{ifthenelse(\tot>1,1,0)}% check if there
%are at least two intersections
\xdef\XNonTriv{\NonTriv}% export the result
};
\end{scope}
\ifnum\XNonTriv=1
\draw[red,very thick,rounded corners,
intersection segments={of=pathone and pathtwo,
sequence=L1--R2 L3}];
\fi
\end{tikzpicture}
\end{document}
随着收益率的上升,这个圈子也向下移动了\pgfmathsetmacro\CY{5}
。
请注意,交叉点必须绘制在范围之外。
下面是一个代码,可以找出交叉点的位置。免责声明:如果圆穿过圆角,则不起作用。您最可能遵循的路径是\mypathA arc(\angleA:\angleB:\CR) --\mypathB
。
\documentclass{standalone}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{graphicx}
\usetikzlibrary{intersections,calc}
\makeatletter
% from https://tex.stackexchange.com/q/56353/121799
\newcommand{\gettikzxy}[3]{%
\tikz@scan@one@point\pgfutil@firstofone#1\relax
\edef#2{\the\pgf@x}%
\edef#3{\the\pgf@y}%
}
\makeatother
\def\mytolerance{0.2}% tolerance for comparing coordinates
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro\minX{2}
\pgfmathsetmacro\maxX{10}
\pgfmathsetmacro\minY{4}
\pgfmathsetmacro\maxY{10}
\pgfmathsetmacro\CX{9}
\pgfmathsetmacro\CY{9}
\pgfmathsetmacro\CR{2}
\pgfmathsetmacro\Roundness{0.2}
\begin{scope} [local bounding box=BoxWest]
\def\pathone{(.5*\maxX + .5*\minX,\maxY)
-- (-\Roundness + \maxX,\maxY)
arc (90:0:\Roundness)
-- (\maxX,\minY +\Roundness)
arc (360:270:\Roundness)
-- (.5*\maxX+ .5*\minX,\minY )}
\path [name path=pathone, draw=green] \pathone;
\path [name path=pathtwo, draw=blue](\CX,\CY)
circle (\CR);
\path [name intersections={of=pathone and pathtwo,name=myint,total=\tot}]
\pgfextra{
\pgfmathtruncatemacro{\NonTriv}{ifthenelse(\tot>1,1,0)}% check if there
\ifnum\NonTriv=1\relax
\gettikzxy{(.5*\maxX + .5*\minX,\maxY)}{\tmpx}{\yplus}
\gettikzxy{(\maxX,0)}{\xmax}{\tmpy}
\gettikzxy{(.5*\maxX+ .5*\minX,\minY )}{\tmpx}{\yminus}
\foreach \X in {1,...,\tot}
{
\gettikzxy{(myint-\X)}{\myx}{\myy}
\gettikzxy{(\CX,\CY)}{\circX}{\circY}
\ifnum\X=1
\pgfmathparse{mod(720+atan2(+\myy-\circY,+\myx-\circX),360)}
\xdef\angleA{\pgfmathresult}
%\typeout{angle\space A:\angleA}
\else
\pgfmathparse{mod(720+atan2(+\myy-\circY,+\myx-\circX),360)}
\xdef\angleB{\pgfmathresult}
%\typeout{angle\space B:\angleB}
\fi
\pgfmathtruncatemacro{\isontop}{ifthenelse(abs(\myy-\yplus)<\mytolerance,1,0)}
\ifnum\isontop=1\relax%
%\node at (myint-\X) {\X\ is on top};
\ifnum\X=1
\xdef\mypathA{(.5*\maxX + .5*\minX,\maxY) -- ($(\CX,\CY)+(\angleA:\CR)$)}
\else
\xdef\mypathB{($(\CX,\CY)+(\angleB:\CR)$) -- (-\Roundness + \maxX,\maxY)
arc (90:0:\Roundness) -- (\maxX,\minY +\Roundness)
arc (360:270:\Roundness)
-- (.5*\maxX+ .5*\minX,\minY )}
\fi
\fi%
\pgfmathtruncatemacro{\isonbottom}{ifthenelse(abs(\myy-\yminus)<\mytolerance,1,0)}
\ifnum\isonbottom=1\relax%
%\node at (myint-\X) {\X\ is on bottom};
\ifnum\X=1
\xdef\mypathA{(.5*\maxX + .5*\minX,\maxY) -- (-\Roundness + \maxX,\maxY)
arc (90:0:\Roundness)
-- (\maxX,\minY +\Roundness)
arc (360:270:\Roundness)
-- ($(\CX,\CY)+(\angleA:\CR)$)}
\else
\xdef\mypathB{($(\CX,\CY)+(\angleB:\CR)$) -- (.5*\maxX+ .5*\minX,\minY )}
\fi
\fi%
\pgfmathtruncatemacro{\isonright}{ifthenelse(abs(\myx-\xmax)<\mytolerance,1,0)}
\ifnum\isonright=1\relax%
%\node at (myint-\X) {\X\ is on right};
\ifnum\X=1
\xdef\mypathA{(.5*\maxX + .5*\minX,\maxY)-- (-\Roundness + \maxX,\maxY)
arc (90:0:\Roundness)
-- ($(\CX,\CY)+(\angleA:\CR)$)
}
\else
\xdef\mypathB{($(\CX,\CY)+(\angleB:\CR)$) -- (\maxX,\minY +\Roundness)
arc (360:270:\Roundness)
-- (.5*\maxX+ .5*\minX,\minY )}
\fi
\fi%
%\typeout{\X : \myx,\myy,\yplus,\yminus,\xmax}
}
%\typeout{\mypathA arc(\angleA:\angleB:\CR) --\mypathB}
\draw[red] \mypathA arc(\angleA:\angleB:\CR) --\mypathB ;
\else
\fi
};
\end{scope}
\end{tikzpicture}
\end{document}