
tikz를 이용하여 상당히 간단한 장면을 그려보려고 합니다.
내가 가진 문제는 반원의 끝점을 정의하는 것입니다. 교차점 감지를 위한 알고리즘을 구현하려고 시도했는데 의사 코드는 다음에서 찾을 수 있습니다.원형-선 교차점. 그러나 제대로 작동하지 않습니다. 또한 해당 \ifthenelse
절을 사용하면 컴파일되지 않습니다.
이 작업을 수행하는 방법에 대한 제안이 있으십니까?
\documentclass[11pt]{article}
\usepackage{tikz}
\usepackage{ifthen}
\usepackage{graphics, tkz-berge, tkz-graph}
%%%<
\usepackage{verbatim}
\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}
\setlength\PreviewBorder{5pt}%
%%%>
\tikzset{isometricXYZ/.style={x={(-0.866cm,-0.5cm)}, y={(0.866cm,-0.5cm)}, z={(0cm,1cm)}}}
%% document-wide tikz options and styles
\begin{document}
\begin{tikzpicture} [scale=4, line join=round,
opacity=.75, fill opacity=.35, text opacity=1.0,%
>=latex,
inner sep=0pt,%
outer sep=2pt,%
]
% First argument is a ray angle, second argument is an offset along x-axis.
\newcommand{\ray}[2]{
\def\r{1} % sphere radius
\def\l{2} % line length
\def\xc{#2} % offset
% Sphere center
\def\Cx{0}
\def\Cy{0}
% Ray start
\def\Ex{(\xc + (\l*cos(#1)))}
\def\Ey{(\l*sin(#1))}
% Ray end
\def\Lx{\xc}
\def\Ly{0}
% Vector from ray start to end
\def\dx{(\Lx -\Ex)}
\def\dy{(\Ly -\Ey)}
% Vector from ray start sphere center
\def\fx{(\Ex - \Cx)}
\def\fy{(\Ey - \Cy)}
% solve eq
\def\a{(\dx * \dx + \dy * \dy)}
\def\b{(2 * \fx * \dx + \fy * \dy)}
\def\c{(\fx * \fx + \fy * \fy - \r * \r)}
\def\discriminant{(\b*\b - 4*\a*\c)}
\ifthenelse{{\discriminant} < 0}
{
\def\endc{(\xc, 0)}
}
{
\def\sqdiscriminant{sqrt(\discriminant)}
\def\t{(-\b +\sqdiscriminant)/(2*\a)}
\def\endc{({\Ex + \t*\dx}, {\Ey + \t*\dy})}
}
\def\startc{({\Ex}, {\Ey})}
\draw [->] \startc -- \endc;
}
\draw[fill=gray, fill opacity=0.2] (1, 0) arc (0:180:1);
\draw [dotted] (0, 0) -- ({cos(30)}, {sin(30)}) node[above right] {$\alpha_1$};
\draw [dotted] (0, 0) -- ({cos(150)}, {sin(150)}) node[above left] {$\alpha_2$};
\draw [dotted] (0, 0) -- (0, 1.1);
\node[below right] (halfpi) at (1, 0) {$\frac{\pi}{2}$};
\node[below left] (minushalfpi) at (-1, 0) {$-\frac{\pi}{2}$};
\foreach \x in {2}
{
\ray{55}{\x}
};
\end{tikzpicture}
\end{document}
아래 두 솔루션을 모두 테스트했지만 두 경우 모두 일부 교차로가 잘못 선택되었습니다. 내 생각엔 내가 모든 경우에 첫 번째 교차로를 선택하기 때문인 것 같은데, 불행히도 항상 올바른 교차로는 아닙니다. 항상 선택하는 방법이 있나요?가장 가까운, 첫 번째 교차로가 아닌가요?
pps :) nvm. 경로 방향을 반대로 해서 해결했습니다.
답변1
intersections
광선과 원의 교차점을 수동으로 계산하지 않으려면 라이브러리를 사용하면 됩니다 . 반원과 선이 결합된 경로와 같이 적당히 복잡한 경로에도 작동합니다.
교차점을 확보하려면가장 가까운"광원"으로 설정하려면 광원에서 광선을 시작한 다음 옵션을 사용할 수 있습니다 sort by=ray
. 이 방법은 (interection-1)
항상 소스에 가장 가까운 방법입니다.
그리고 그렇습니다. TikZ는 TeX
. 요술!
\documentclass[tikz,margin=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture} [scale=4, line join=round, >=latex]
% Name this path for intersections
\draw[fill=gray, fill opacity=0.2, name path=outline]
(-2,0) -- (-1,0) arc (180:0:1)-- (2,0) ;
\draw [dotted] (0, 0) -- ({cos(30)}, {sin(30)}) node[above right] {$\alpha_1$};
\draw [dotted] (0, 0) -- ({cos(150)}, {sin(150)}) node[above left] {$\alpha_2$};
\draw [dotted] (0, 0) -- (0, 1.1);
\node[below right] (halfpi) at (1, 0) {$\frac{\pi}{2}$};
\node[below left] (minushalfpi) at (-1, 0) {$-\frac{\pi}{2}$};
% Properties of the "light source"
\def\angle{45}
\def\width{2.8cm}
% Draw the light source:
\draw[very thick] (\angle:2.5cm) coordinate(light)
++(\angle+90:0.5*\width) -- +(\angle-90:\width);
% Draw a number of rays:
\foreach \x in {-8,...,8} {
% Place a path from light source through circle and name it:
\path[name path=ray,overlay] (light) ++(\angle+90:\x*\width/17)
coordinate(start) -- +(180+\angle:5cm);
% Draw the arrow from light source to first intersection:
\draw[->, name intersections={of=outline and ray, sort by=ray}]
(start) -- (intersection-1);
}
\end{tikzpicture}
\end{document}
답변2
교차점을 선택적으로 그리려는 경우 교차점 발견 여부를 구현할 수도 있습니다. 그러나 교차점 계산은 섬세한 작업이므로 항상 정밀도에 의존할 수는 없습니다.
\documentclass[tikz]{standalone}
\usetikzlibrary{intersections,calc}
\begin{document}
\begin{tikzpicture}[>=latex]
\begin{scope}[fill opacity=.35]
\fill[blue] (4cm,0)--++(40:1cm) arc (40:180:1cm);
\fill[gray] (4cm,0)--++(40:1cm) arc (40:0:1cm);
\end{scope}
\draw[ultra thick] (1cm,2.5cm) coordinate (ls) -- ++(30:4cm) coordinate (le);
\draw[ultra thick,name path=a] (2cm,-2cm)--++(7cm,0);
\draw[ultra thick,name path=b] (5cm,0) arc (0:180:1cm);
\foreach \x[count=\xi] in {0.1,0.15,...,0.9}{
\path[name path global=ray\xi,overlay] ($(ls)!\x!(le)$) --++(-60:15cm);
\draw[->,
name intersections={of=a and ray\xi,name=intaray\xi},
name intersections={of=b and ray\xi,name=intbray\xi}]
\pgfextra{% Test for the shape name existence
\csname pgfutil@ifundefined\endcsname{pgf@sh@ns@intbray\xi-1}{\def\temp{a}}{\def\temp{b}}%
}
($(ls)!\x!(le)$) -- (int\temp ray\xi-1);
}
\end{tikzpicture}
\end{document}