I am trying to draw a fairly simple scene with tikz.
The issue i have is with defining the end points on half circle. I tried to implement an algorithm
for intersection detection, pseudocode can be found at Circle-Line intersection. However it does not work as it should. In addition, it does not compile if i use the \ifthenelse
clause.
Any suggestions on how to get this to work?
\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}
I tested both solutions below, but in both cases i get some intersections picked up incorrectly. I guess that is because i take the first intersection in all cases, which is unfortunately not always the right one. Is there a way to always choose the closest, not the first, intersection?
p.p.s 🙂
nvm. I fixed it by reversing the path direction.
Best Answer
You can simply use the
intersections
library to avoid calculating the intersections of the rays and the circle manually. It even works for moderately complex paths like the combined half-circle-and-line path.In order to get the intersection closest to the "light source", you can start the ray at the light source and then use the option
sort by=ray
. This way,(interection-1)
is always the one closest to the source.And yes, TikZ does all the calculation and sorting using
TeX
. Witchcraft!