Here's another TikZ solution. Given two points on the Poincare plane or disc, it draws the geodesic between them. It does this by defining a (complicated!) to
path which works out the circle and angles and then draws the correct arc. It has some basic error checking to see if it ought to draw a straight line, but it checks for the exact condition rather than to within the precision of TeX so if your points are almost one above the other (or on the same radius) so that to all intents and purposes the geodesic is straight then this code might not detect that in time and end up dividing by something smaller than it should (as it is, I had to be careful how I broke up the calculations as some methods gave Big Numbers at partial stages).
\documentclass{article}
%\url{https://tex.stackexchange.com/a/19168/86}
\thispagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\def\hyper@x#1,#2\relax{#1}
\def\hyper@y#1,#2\relax{#2}
\def\hyper@coords#1{#1}
\newif\ifhyper@vertical
\def\hyper@computer#1#2{%
\edef\hyper@toscan{(#1)}
\tikz@scan@one@point\hyper@coords\hyper@toscan
\edef\hyper@sx{\the\pgf@x}
\edef\hyper@sy{\the\pgf@y}
\edef\hyper@toscan{(#2)}
\tikz@scan@one@point\hyper@coords\hyper@toscan
\edef\hyper@ex{\the\pgf@x}
\edef\hyper@ey{\the\pgf@y}
\pgfmathsetmacro{\hyper@mx}{(\hyper@ex + \hyper@sx)/2}
\pgfmathsetmacro{\hyper@my}{(\hyper@ey + \hyper@sy)/2}
\pgfmathsetmacro{\hyper@dx}{\hyper@ex - \hyper@sx}
\pgfmathparse{\hyper@dx == 0 ? "\noexpand\hyper@verticaltrue" : "\noexpand\hyper@verticalfalse"}
\pgfmathresult
\ifhyper@vertical
\edef\hyper@cmd{-- (\tikztotarget)}
\else
\pgfmathsetmacro{\hyper@dy}{\hyper@ey - \hyper@sy}
\pgfmathsetmacro{\hyper@t}{\hyper@my/\hyper@dx}
\pgfmathsetmacro{\hyper@cx}{\hyper@mx + \hyper@t * \hyper@dy}
\pgfmathsetmacro{\hyper@radius}{veclen(\hyper@cx - \hyper@sx, \hyper@sy)}
\pgfmathsetmacro{\hyper@sangle}{180 - atan2(\hyper@sy,\hyper@cx-\hyper@sx)}
\pgfmathsetmacro{\hyper@eangle}{180 - atan2(\hyper@ey,\hyper@cx-\hyper@ex)}
\edef\hyper@cmd{arc[radius=\hyper@radius pt, start angle=\hyper@sangle, end angle=\hyper@eangle]}
\fi
}
\def\hyper@disc@computer#1#2{%
\edef\hyper@toscan{(#1)}
\tikz@scan@one@point\hyper@coords\hyper@toscan
\edef\hyper@sx{\the\pgf@x}
\edef\hyper@sy{\the\pgf@y}
\edef\hyper@toscan{(#2)}
\tikz@scan@one@point\hyper@coords\hyper@toscan
\edef\hyper@ex{\the\pgf@x}
\edef\hyper@ey{\the\pgf@y}
\pgfmathsetmacro{\hyper@det}{\hyper@sx * \hyper@ey - \hyper@sy * \hyper@ex}
\pgfmathparse{\hyper@det == 0 ? "\noexpand\hyper@verticaltrue" : "\noexpand\hyper@verticalfalse"}
\pgfmathresult
\ifhyper@vertical
\edef\hyper@cmd{-- (\tikztotarget)}
\else
\pgfmathsetmacro{\hyper@mx}{(\hyper@ex + \hyper@sx)/2}
\pgfmathsetmacro{\hyper@my}{(\hyper@ey + \hyper@sy)/2}
\pgfmathsetmacro{\hyper@dx}{\hyper@ex - \hyper@sx}
\pgfmathsetmacro{\hyper@dy}{\hyper@ey - \hyper@sy}
\pgfmathsetmacro{\hyper@dradius}{\pgfkeysvalueof{/tikz/hyperbolic disc radius}}
\pgfmathsetmacro{\hyper@t}{((\hyper@dradius)^2 - \hyper@sx * \hyper@ex - \hyper@sy * \hyper@ey)/(2 * (\hyper@sx * \hyper@ey - \hyper@sy * \hyper@ex))}
\pgfmathsetmacro{\hyper@radius}{sqrt((\hyper@t)^2 + .25) * veclen(\hyper@dx,\hyper@dy)}
\pgfmathsetmacro{\hyper@cx}{\hyper@mx + \hyper@t * \hyper@dy}
\pgfmathsetmacro{\hyper@cy}{\hyper@my - \hyper@t * \hyper@dx}
\pgfmathsetmacro{\hyper@sangle}{atan2(\hyper@sy-\hyper@cy,\hyper@sx - \hyper@cx)}
\pgfmathsetmacro{\hyper@eangle}{atan2(\hyper@ey-\hyper@cy,\hyper@ex - \hyper@cx)}
\pgfmathsetmacro{\hyper@eangle}{\hyper@eangle > \hyper@sangle + 180 ? \hyper@eangle - 360 : \hyper@eangle}
\edef\hyper@cmd{arc[radius=\hyper@radius pt, start angle=\hyper@sangle, end angle=\hyper@eangle]}
\fi
}
\def\hyper@plane@tangent#1#2{%
\edef\hyper@toscan{(#1)}
\tikz@scan@one@point\hyper@coords\hyper@toscan
\edef\hyper@sx{\the\pgf@x}
\edef\hyper@sy{\the\pgf@y}
\edef\hyper@toscan{(#2)}
\tikz@scan@one@point\hyper@coords\hyper@toscan
\edef\hyper@ex{\the\pgf@x}
\edef\hyper@ey{\the\pgf@y}
% The difference between the end and start defines the tangent
% vector
\pgfmathsetmacro{\hyper@ex}{\hyper@ex - \hyper@sx}
\pgfmathsetmacro{\hyper@ey}{\hyper@ey - \hyper@sy}
% If we're straight up ...
\pgfmathparse{\hyper@ex == 0 ? "\noexpand\hyper@verticaltrue" : "\noexpand\hyper@verticalfalse"}
\pgfmathresult
\ifhyper@vertical
% Need to set length here, rescale to cm first
% User \hyper@ey here as that remembers the sign
\pgfmathsetmacro{\hyper@d}{\hyper@ey/1cm}
\pgfmathsetmacro{\hyper@radius}{\hyper@sy * exp(\hyper@d) - \hyper@sy}
\edef\hyper@cmd{-- ++(0,\hyper@radius pt)}
\else
% Set length
\pgfmathsetmacro{\hyper@d}{\hyper@ex > 0 ? veclen(\hyper@ex,\hyper@ey) : -veclen(\hyper@ex,\hyper@ey)}
% Radius of arc
\pgfmathsetmacro{\hyper@radius}{abs(\hyper@sy * \hyper@d / \hyper@ex)}
% Starting angle
\pgfmathsetmacro{\hyper@sangle}{90 + atan(\hyper@ey/\hyper@ex)}
% Ending angle, check if given
\pgfkeysgetvalue{/tikz/hyperbolic plane target angle}{\hyper@eangle}
\ifx\hyper@eangle\pgfutil@empty
% rescale into cm to avoid Big Numbers
\pgfmathsetmacro{\hyper@d}{\hyper@d/1cm}
\pgfmathsetmacro{\hyper@ey}{\hyper@ey/1cm}
\pgfmathsetmacro{\hyper@tanhd}{tanh(\hyper@d)}
\pgfmathsetmacro{\hyper@eangle}{acos((\hyper@d * \hyper@tanhd - \hyper@ey)/(\hyper@d - \hyper@ey * \hyper@tanhd))}
%
\fi
\edef\hyper@cmd{arc[radius=\hyper@radius pt, start angle=\hyper@sangle, end angle=\hyper@eangle]}
\fi
}
\tikzset{%
hyperbolic disc radius/.initial={1cm},
hyperbolic plane/.style={
to path={
\pgfextra{\hyper@computer\tikztostart\tikztotarget}
\hyper@cmd
}
},
hyperbolic plane tangent/.style={
to path={
\pgfextra{\hyper@plane@tangent\tikztostart\tikztotarget}
\hyper@cmd
}
},
hyperbolic disc/.style={
to path={
\pgfextra{\hyper@disc@computer\tikztostart\tikztotarget}
\hyper@cmd
}
},
hyperbolic plane target angle/.initial={},
}
\makeatother
\begin{document}
\begin{tikzpicture}[every to/.style={hyperbolic plane}]
\fill[blue] (0,1) \foreach \k in {0,...,7} { to ++(\k * 45:2)};
\coordinate (b) at (1,2);
\coordinate (a) at (3,4);
\fill (a) circle[radius=2pt];
\fill (b) circle[radius=2pt];
\draw (-2,0) -- (6,0);
\draw (a) to (b);
\end{tikzpicture}
\begin{tikzpicture}[hyperbolic disc radius=2cm,
every to/.style={hyperbolic disc}]
\draw (0,0) circle[radius=\pgfkeysvalueof{/tikz/hyperbolic disc radius}];
\pgfmathsetmacro{\hyperrad}{1/(2*sin(22.5))}
\fill[blue] (-112.5:\hyperrad) \foreach \k in {0,...,7} { to ++(\k * 45:1)};
\coordinate (b) at (1.2,.3);
\coordinate (a) at (.8,-.4);
\fill (a) circle[radius=2pt];
\fill (b) circle[radius=2pt];
\draw (a) to (b);
\end{tikzpicture}
\begin{tikzpicture}[every to/.style={hyperbolic plane tangent}]
\draw (1,2) circle[radius=2pt] to ++(1,1) circle[radius=4pt];
\draw[red] (-1,2) circle[radius=2pt] to[hyperbolic plane target angle=0] ++(-60:2) circle[radius=4pt];
\draw (0,1) circle[radius=2pt] \foreach \k in {0,...,7} { to ++(\k * 45:1)};
\draw[thick,gray,<->] let \p{east}=(current bounding box.east), \p{west}=(current bounding box.west) in (\x{east},0) -- (\x{west},0);
\end{tikzpicture}
\end{document}
Result:

One extension that would be nice would be to be able to draw an arc from a point starting in a particular direction and going on for a particular length. A hyperbolic version of the Euclidean \draw (1,0) -- ++(45:2);
.