sweep.w
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:80k
开发平台:

MultiPlatform

  1. documentstyle[11pt,comments,a4]{cweb}
  2. voffset=-0.5cm
  3. textwidth 14cm
  4. oddsidemargin          0.4cm
  5. evensidemargin         1.4cm
  6. marginparwidth 1.9cm
  7. marginparsep 0.4cm
  8. marginparpush 0.4cm
  9. topmargin 0cm
  10. headsep 1.5cm
  11. textheight 21.5cm
  12. footskip 2.2cm
  13. input transfig
  14. input papermacros
  15. begin{document}
  16. renewcommand{thefootnote}{fnsymbol{footnote}}
  17. title{Implementation of a Sweep Line Algorithm for the\
  18.        Straight Line Segment Intersection Problem}
  19. author{Kurt Mehlhorn and Stefan N"aher\
  20.        {footnotesize  Max-Planck-Institut f"ur Informatik,}\[-0.7ex]
  21.        {footnotesize 66123 Saarbr"ucken, Germany}}
  22.  
  23.         date{} 
  24.         maketitle
  25. @i typnamen
  26. @s myPoint int
  27. @s mySegment int
  28. @* Abstract.
  29. We describe a robust and efficient implementation of the Bentley-Ottmann 
  30. sweep line algorithm cite{Bentley-Ottmann} based on the LEDA library
  31. of efficient data types and algorithms cite{LEDA-Paper}. The program 
  32. computes the planar graph $G$ induced by a set $S$ of straight line segments 
  33. in the plane. The nodes of |G| are all endpoints and all proper intersection 
  34. points of segments in |S|. The edges of |G| are the maximal relatively open 
  35. subsegments of segments in |S| that contain no node of |G|. All edges are
  36. directed from left to right or upwards.
  37. The algorithm runs in time $O((n+s)log n)$ where $n$ is the number of 
  38. segments and $s$ is the number of vertices of the graph $G$. The implementation
  39. uses exact arithmetic for the reliable realization of the geometric 
  40. primitives and it uses floating point filters to reduce the overhead of
  41. exact arithmetic.
  42. tableofcontents
  43. @* Introduction.
  44. Let $S$ be a set of $n$ straight-line segments in the plane and let $G(S)$
  45. be the graph induced by $S$. The vertices of $G(S)$ are all endpoints of
  46. segments in $S$ and all intersection points between segments in $S$. The edges 
  47. of $G$ are the maximal relatively open and connected subsets of segments in
  48. $S$ that contain no vertex of $G(S)$. Figure ref{example} shows an example.
  49. Note that the graph $G(S)$ contains no parallel edges even if $S$ contains segments that overlap.
  50. begin{figure}
  51. begin{center}
  52. input{figures/introfig.tex}
  53. caption{label{example}A set $S$ of segments and the induced planar graph.}
  54. end{center}
  55. end{figure}
  56. Bentley and Ottmann cite{Bentley-Ottmann} have shown how to compute $G(S)$
  57. in time $O((n+m)log n)$ where $m$ is the number of pairs of intersecting
  58. segments in $S$. The algorithm is based on the plane-sweep paradigm. We
  59. refer the reader to cite[section VIII.4]{Mehlhorn-book}
  60. cite[section 7.2.3]{Preparata-Shamos}, and 
  61. cite[section 35.2]{Cormen-Leiserson-Rivest}
  62. for a discussion of the plane sweep paradigm.
  63. In this paper we describe an implementation of the Bentley-Ottmann algorithm. 
  64. More precisely, we define a procedure
  65. begin{center}
  66.   |sweep_segments(list<rat_segment> &seglist,GRAPH<rat_point,rat_segment> &G,bool use_filter)|
  67. end{center}
  68. that takes a list $seglist$ of |rat_segment|s (segments with rational coordinates)
  69. and computes the graph $G$ induced by it. For each vertex $v$ of $G$ it also 
  70. computes its position in the plane, a |rat_point| (a point with rational 
  71. coordinates) and for each edge $e$ of $G$ it computes a |rat_segment| containing 
  72. it. The algorithm is based on the LEDA platform for combinatorial and geometric 
  73. computing cite{LEDA-Paper,LEDA-Manual}. In LEDA a |rat_segment| is specified by 
  74. its two endpoints (of type |rat_point|) and a |rat_point| is specified by its 
  75. homogeneous coordinates $(X,Y,W)$ of type |integer|. The type |integer| is the type 
  76. of arbitrary precision integers. 
  77. If |use_filter| is set to |true| then there must be
  78. integers $k$ and $l$ such that $5k+3lleq 450$ and 
  79. $^^7cX^^7c,^^7cY^^7cleq 2^k$ and $1leq ^^7cW^^7cleq 2^l$ for all 
  80. endpoints. In section ref{float-restrictions} we will explain 
  81. where this restriction on the input size comes from. Use of the filter increases
  82. the speed of the program by up to a factor of 4.
  83. We want to stress that the implementation makes no other assumptions
  84. about the input, in particular, segments may have length zero, may overlap,
  85. several segments may intersect in the same point, endpoints of segments may
  86. lie in the interior of other segments, ... .
  87. We have achieved this generality by following two principles.
  88. begin{itemize}
  89. item
  90. Treat degeneracies as first class citizens and not as an afterthought
  91. cite{Burnikel-et-al}. In particular, we reformulated the plane-sweep
  92. algorithm so that it can handle all geometric situations. The details will
  93. be given in section ref{Algorithm}. The reformulation makes the 
  94. description of the algorithm shorter since we do not distinguish between
  95. three kinds of events but have only one kind of event and it also makes the 
  96. algorithm faster. The algorithm now runs in time $O((n+s)log n)$ where
  97. $s$ is the number of vertices of $G$. Note that $sleq n+m$ and that $m$
  98. can be as large as $s^2$. The only previous algorithm that could handle all
  99. degeneracies is due to Myers cite{Myers}. Its expected running time for
  100. random segments is $O(n log n + m)$ and its worst case running time is
  101. $O((n + m) log n)$.
  102. item
  103. Evaluate all geometric tests exactly. We use arbitrary precision integer
  104. arithmetic for all geometric computations. So all tests are computed exactly
  105. and we do not have to worry about numerical precision. Of course, we have
  106. to pay for the overhead of arbitrary precision integer arithmetic. In order
  107. to keep the overhead low we followed the suggestion of Fortune and van Wyk
  108. cite{Fortune-vanWyk} and implemented a floating point filter, i.e., all tests
  109. are first performed using floating point arithmetic and only if the result of
  110. the floating point computation is inconclusive we perform the costly exact
  111. computation. The floating point filter improves the running time by a factor
  112. of up to 4 depending on the problem instance. The floating point filter
  113. is responsible for the restrictions that we have to place on the input.
  114. The restrictions guarantee that the floating point computations will not
  115. overflow.
  116. end{itemize}
  117. This paper is structured as follows. In section ref{Algorithm} we describe the
  118. (generalized) plan-sweep algorithm. Section ref{Implementation}
  119. and ref{geometric primitives} give the details of the implementation: the 
  120. former section describes the combinatorial part and the latter section describes
  121. the geometric primitives. The floating point filter is also discussed there.
  122. Section ref{experiments} contains some experimental results.
  123. @* The Algorithm. 
  124. label{Algorithm}
  125. In the sweep-line paradigm a line is moved from left to right across the plane
  126. and the output (here the graph $G(S)$) is constructed incrementally as it
  127. evolves
  128. behind the sweep line. One maintains two data structures to keep the
  129. construction going: The so-called {em Y-structure} contains the intersection
  130. of
  131. the sweep line with the scene (here the set $S$ of line segments) and the
  132. so-called
  133. {em X-structure} contains the events where the sweep has to be
  134. stopped in order to add to the output or to update the $X$- or $Y$-structure.
  135. In the line segment intersection problem an event occurs when the sweep line
  136. hits an endpoint of some segment or an intersection point. When an event
  137. occurs, some nodes and edges are added to the graph $G(S)$, the $Y$-structure
  138. is
  139. updated, and maybe some more events are generated. When the input is in
  140. general position (no three lines intersecting in a common point, no endpoint
  141. lying on a segment, no two endpoints or intersections having the same
  142. $x$-coordinate, no vertical lines, no overlapping segments) then at most one
  143. event can occur for each position of the sweep line and there are three clearly
  144. distiguishable types of events (left endpoint, right endpoint, intersection)
  145. with easily describable associated actions, cf. 
  146. cite{Mehlhorn-book}(section VIII.4).
  147. We want to place no restrictions on the input and therefore need to proceed
  148. slightly differently. We now describe the required changes.
  149. We define the sweep line by a point $p_sweep = (x_sweep, y_sweep)$. Let
  150. $epsilon$ be a positive infinitesimal (readers not familiar with
  151. infinitesimals may think of $epsilon$ as an arbitrarily small positive real).
  152. Consider the directed line $L$ consisting of a vertical upward ray ending in
  153. point $(x_sweep + epsilon, y_sweep + epsilon)$ followed by a horizontal
  154. segment ending in $(x_sweep - epsilon, y_sweep + epsilon)$ followed by a
  155. vertical upward ray. We call $L$ the {em sweep line}. Note that no endpoint
  156. of any segment lies on $L$, that no two segments of $S$ intersect $L$ in the
  157. same point except if the segments overlap, and that no non-vertical segment
  158. of $S$ intersects the horizontal part of $L$. All three properties follow from
  159. the fact that $epsilon$ is arbitrarily small but positive. Figure ref{the
  160. sweep line} illustrates the definition of $L$ and the data structures used in
  161. the algorithm: The $Y$-structure, the $X$-structure, and the graph |G|.
  162. begin{figure}
  163. begin{center}
  164. input{figures/sw2fig.tex}
  165. caption{label{the sweep line}A scene of 9 segments. The segments $s_1$ and
  166. $s_8$ overlap. The $Y$-structure contains segments $s_1$, $s_2$, $s_9$, $s_4$,
  167. and $s_3$ and the $X$-structure contains points $a$, $b$, $c$, $d$, $e$, $f$,
  168. $g$, $h$, and $i$. An item in the $X$-structure containing point
  169. $p$
  170. is denoted $xit_p$ and an item in the $Y$-structure containing segment $s_i$
  171. is denoted $sit_i$. The vertices of the graph $G$ are shown as full circles.}
  172. end{center}
  173. end{figure}
  174. The $Y$-structure contains all
  175. segments intersecting the sweep line $L$ ordered as their intersections with
  176. $L$ appear on the directed line $L$. For segments intersecting $L$ in the same
  177. point (these segments necessarily have the same underlying line) only the
  178. segment extending further to the right is stored in the $Y$-structure. 
  179. In the example of Figure ref{the sweep line} the sweep line intersects the
  180. segments $s_8$, $s_1$, $s_2$, $s_9$, $s_4,$ and $s_3$. The segments $s_8$ and
  181. $s_1$
  182. intersect $L$ in the same point and $s_1$ extends further to the right. Thus
  183. $s_1$ is stored in the $Y$-structure and $s_8$ is not. The $Y$-structure
  184. therefore consists of five items, one each for segments $s_1$,$s_2$, $s_9$,
  185. $s_4,$ and
  186. $s_3$.
  187. The $X$-structure is a sorted sequence.
  188. It contains an item for each point in $Stcup Ecup I$, where $St$ is the set
  189. of all start points of segments that lie to the right of $L$, $E$ is the set of
  190. all endpoints of segments that intersect $L$, and $I$ is defined as follows.
  191. Every point in $I$ is the intersection $scap s'$ of two segments $s$ and $s'$
  192. adjacent in the $Y$-structure that lies to the right of the sweep line. The ordering of
  193. the points in the $X$-structure is the lexicographic ordering, i.e.,
  194. $(x,y)$ is before $(x',y')$ if either $x<x'$ or $x=x'$ and $y<y'$.
  195. In the example of Figure ref{the sweep line} we have $St = {a,d,e},
  196. E = {b,c,f,e,g,i,h}$ and $I ={f,a}$. The $X$-structure 
  197. therefore
  198. contains 9 items, one each for points |a|, |b|, |c|, |d|, |e|, |f|, |g|, 
  199. |h|, and |i|.
  200. We next define the informations associated with the items of both structures.
  201. These informations serve to link the items in the $X$-structure with the items
  202. in the $Y$-structure and vice versa. In particular, any item in the
  203. |X|-structure is a pair $<p,sit>$ where |p| is a point and |sit| is either
  204. |nil| or an item in the |Y|-structure and any item in the |Y|-structure 
  205. is a pair $<s,xit>$ where |s| is a segment and |xit| is either |nil|
  206.  or an item in the |X|-structure. Let
  207. $<p,sit>$ be any item in the $X$-structure. If $pin Icup E$ then $sit$ is an
  208. item in the $Y$-structure such that the segment associated with $sit$ contains
  209. $p$. If $pin Stsetminus (Icup E)$ then $sit = nil$. Next consider an item
  210. $<s,xit>$ in the
  211. $Y$-structure and let $s'$ be the segment associated with the successor
  212. item in the $Y$-structure. If $scap s'$ exists and lies to the right of the
  213. sweep line then $xit$ is an item in the $X$-structure and $scap s'$ is the
  214. point associated with that item. If $scap s'$ either does not exist or does
  215. not lie to the right of $L$ then $xit = nil$.
  216. In our example, the $Y$-structure contains the items $<s_1,xit_f>, <s_2,nil>$,
  217. $<s_9,nil>, <s_4,xit_a>$ and $<s_3,nil>$ where $xit_a$ and $xit_f$ are the
  218. items
  219. of the $X$-structure with associated points $a$ and $f$ respectively. Let's
  220. turn to the items of the $X$-structure next. All items except $<d,nil>$ point
  221. back to the $Y$-structure. If $sit_i$ denotes the item $<s_i$,...$>$, $iin%
  222. {1,2,9,4,3}$, of the $
  223. Y$-structure then the items of the $X$-structure are $<a,sit_4>,
  224. <b,sit_4>$, $<c,sit_1>, <d,nil>, <e,sit_9>, <f,sit_1>, <g,sit_2>, <h,sit_3>$
  225. and $<i,sit_1>$.
  226. The graph $G$ is the part of $G(S)$ to the left of $L$. With each vertex of
  227. $G$ we store its position and with each edge of $G$ we store a segment
  228. containing it. 
  229. There is one additional piece of information that we need to keep. For each
  230. segment $s$ contained in the $Y$-structure we store the rightmost vertex of $G$
  231. lying on $s$.
  232. We can now give the details of the algorithm. Initially, $G$ and the
  233. $Y$-structure are empty, and the $X$-structure contains the left endpoints of
  234. all segments in $S$.
  235. In order to process an event we proceed as follows. Let $<p,sit>$ be the first
  236. item in the $X$-structure. We may assume inductively that all invariants hold
  237. for $p_sweep = (p.x,p.y-2epsilon)$. Note that this is true initially, i.e.,
  238. before the first event is removed from the $X$-structure. We now show how to
  239. establish the invariants for $p = p_sweep$. We proceed in seven steps.
  240. begin{enumerate}
  241. item
  242.   We add a node $v$ at position $p$ to our graph $G$.
  243. item
  244.   We determine all segments in the $Y$-structure containing the point $p$.
  245.   These segments form a possibly empty subsequence of the $Y$-structure.
  246. item
  247.   For each segment in the subsequence we add an edge to the graph $G$.
  248.   Its right endpoint is
  249.   $v$ and its other
  250.   endpoint is the vertex stored with the segment $s$.
  251. item
  252.   We delete all segments ending in $p$ from the $Y$-structure.
  253. item
  254.   We reverse the order of the subsequence in the $Y$-structure. This amounts to
  255.   moving the sweep line across the point $p$.
  256. item
  257.   We add all segments starting in $p$ to the $Y$-structure and then associate
  258.   the node $v$ with all segments in the $Y$-structure containing $v$. If a
  259.   newly inserted segment is collinear to an already existing segment
  260.   we make
  261.   sure to only keep the segment extending further to the right.
  262. item
  263.   We update the events associated with the items of the $Y$-structure. We
  264.   remove the events associated with the predecessor of the subsequence and
  265.   the last item of the subsequence and we generate new
  266.   events for the predecessor of the first item and the last item after the
  267.   reversal of the subsequence.
  268. end{enumerate}
  269. This completes the description of how to process the event $<p,...>$. The
  270. invariants now hold for $p_sweep = p$ and hence also for
  271. $p_sweep = (p'.x,p'.y-2epsilon)$ where $<p',...>$ is the new first element of
  272. the $X$-structure.
  273. @* The Implementation. 
  274. label{Implementation}
  275. The implementation follows the algorithm closely. 
  276. There are two main differences.
  277. begin{itemize}
  278. item
  279.   We add two infinitely long horizontal segments with $y$-coordinate
  280.   $+infty$ and $-infty$ respectively. They serve as sentinels and simplify
  281.   many tests. 
  282. item
  283.   We maintain all points twice: once by their exact
  284.   homogeneous coordinates and once by floating point approximations to
  285.   these coordinates. All tests are first performed using the floating point
  286.   approximations and only if the floating point filter gives no conclusive
  287.   result the test is performed using exact arithmetic. 
  288. end{itemize}
  289. We use sorted sequences, graphs, rational points and segments, big integers, 
  290. and a floating point filter from LEDA, and some functions of the C++ maths 
  291. library. We have to include the corresponding header files.
  292. @<include statements@> =
  293. #include <LEDA/sortseq.h>
  294. #include <LEDA/graph.h>
  295. #include <LEDA/rat_point.h>
  296. #include <LEDA/rat_segment.h>
  297. #include <LEDA/integer.h>
  298. #include <LEDA/floatf.h>
  299. #include <math.h>
  300. @
  301. Let us briefly explain these types; for a detailed discussion we refer
  302. the reader to the LEDA manual cite{LEDA-Manual}. |integer| is the type of 
  303. arbitrary precision integers and |floatf| is the type of floating point 
  304. approximation to integers. The type |floatf| is defined in section ref{floatf}. 
  305. The types |rat_point| and |rat_segment| realize points and segments in the 
  306. plane with rational coordinates. An |rat_point| is specified by its homogeneous
  307. coordinates of type |integer|. If |p| is a |rat_point| then |p.X()|, |p.Y()|, and
  308. |p.W()| return its homogeneous coordinates and if |X|, |Y|, and |W| are of
  309. type |integer| and $Wneq 0$ then |rat_point(X,Y)| and |rat_point(X,Y,W)| create
  310. the |rat_point| with homogeneous coordinates |(X,Y,1)| and |(X,Y,W)| 
  311. respectively. A |rat_segment| is specified by its two endpoints; so if 
  312. |p| and |q| are |rat_point|s then |rat_segment(p,q)| constructs the directed
  313. |rat_segment| with startpoint |p| and endpoint |q|. If |s| is a |rat_segment| then
  314. |s.start()| and |s.end()| return the start- and endpoint of |s| respectively 
  315. and |s.dx()| and |s.dy()| return the normalized |x|- and |y|-difference
  316. of the segment, i.e., if |(px,py,pw)| and |(qx,qy,qw)| are the
  317. homogeneous coordinates of the start- and endpoint of |s| then
  318. |s.dx()| returns $pxcdot qw - qxcdot pw$ and |s.dy()| returns
  319. $pycdot qw - qycdot pw$. The slope of a segment |s| is given by
  320. $s.dy()/s.dx()$, but be careful. The slope might be infinite (if the
  321. segment is vertical) or undefined (if the segment has length zero).
  322. @s K int
  323. @s Inf int
  324. For any types |K| and |Inf| the type |sortseq<K,Inf>| is the type of sorted
  325. sequences of pairs in $Ktimes Inf$. The type |K| must be linearly ordered 
  326. by a function |compare|, i.e., the function 
  327. |int compare(const K&, const K&)| must be defined for the type |K|
  328. and the relation $<$ on |K| defined by $k_1 < k_2$ iff 
  329. $compare(k_1,k_2) < 0$ is a linear order on |K|. Any object of type
  330. |sortseq<K,Inf>| is a sequence of items (type |seq_item|) each containing
  331. a pair $Ktimes Inf$. We use |<k,i>| to denote an item containing the pair
  332. $(k,i)$ and call |k| the key and |i| the information of the item. A sorted 
  333. sequence $<k_1,i_1>$,$<k_2,i_2>$,dots ,$<k_m,i_m>$ has the additional
  334. property that the keys of the item form an increasing sequence, i.e.,
  335. $k_l < k_{l+1}$ for $1leq l<m$.
  336. In our implementation the |X|-structure has type |sortseq<rat_point,seq_item>|
  337. and the |Y|-structure has type |sortseq<rat_segment,seq_item>|. We will later 
  338. define the appropriate compare functions. If |p| and |q| are points with
  339. cartesian coordinates |px|, |py|, |qx|, and |qy| respectively then
  340. [ compare(p,q) = left {
  341.                   begin{array}{rl}
  342.   -1 & mbox{ if }px<qxmbox{ or }px=qxmbox{ and }py<qy\
  343.   0  & mbox{ if }px=qxmbox{ and }py=qy\
  344.   +1 & mbox{ otherwise, }
  345.   end{array}
  346.   right . 
  347. ]
  348. and if |s1| and |s2| are segments intersecting the sweep line |L| then
  349. |compare(s1,s2) = -1| if $s1cap L$ precedes $s2cap L$ on |L|,
  350. |compare(s1,s2) = 0| if $s1cap L = s2cap L$, and
  351. |compare(s1,s2) = +1| if $s1cap L$ comes after $s2cap L$.
  352. It is important to observe that the compare function for segments
  353. changes as the sweep progresses. What does it mean then that the keys of the 
  354. items in a sorted sequence form an increasing sequence? LEDA requires 
  355. that whenever a lookup or insert operation is applied to a sorted
  356. sequence the sequence must be sorted with respect to the current 
  357. compare function. The other operations may be applied even if the 
  358. sequence is not sorted. What operations are available?
  359. Let |S| be a sorted sequence of type |sortseq<K,Inf>| and let |k| 
  360. and |i| be of type |K| and |Inf| respectively. The operation 
  361. |S.lookup(k)| returns the item $it = <k,.>$ in |S| with key |k| if there
  362. is such an item and returns |nil| otherwise. If |S.lookup(k)==nil|
  363. then |S.insert(k,i)| adds a new item |<k,i>| to |S| and returns
  364. this item. If |S.lookup(k)==it| then |S.insert(k,i)| changes the
  365. information in the item |it| to |i|. If $it=<k,i>$ is an item of |S|
  366. then |S.key(it)| and |S.inf(it)| return |k| and |i| respectively and
  367. |S.succ(it)| and |S.pred(it)| return successor and predecessor item
  368. of |it| respectively; the latter operations return |nil| if these
  369. items do not exist. The operation |S.min()| returns the first item
  370. of |S|, |S.empty()| returns true if |S| is empty and false otherwise. 
  371. Finally, if |it1| and |it2| are items of |S| with |it1| before |it2|
  372. then |S.reverse_items(it1,it2)| reverses the subsequence of |S| 
  373. starting at item |it1| and ending at item |it2|. The requirement for
  374. this operation is that the sequence |S| is sorted with respect to
  375. the current compare function after the operation.
  376. The graph |G| to be constructed has type |GRAPH<rat_point,rat_segment>|, i.e.,
  377. it is a directed graphs where a |rat_point| (|rat_segment|) is associated with
  378. each node (edge) of the graph. If |p| is a |rat_point| then
  379. |G.new_node(p)| adds a new node to |G|, associates |p| with the node,
  380. and returns the new node. If |v| and |w| are nodes of |G| and |s|
  381. is a |rat_segment| then |G.new_edge(v,w,s)| adds the edge |(v,w)| to |G|, 
  382. associates |s| with the edge, and returns the new edge.
  383. @* The Basic Program Structure.
  384. Our program has the following structure.
  385. @c
  386. @<include statements@>@;
  387. @<global types and declarations@>@;
  388. @<geometric primitives@>@;
  389. void sweep(list<rat_segment>& S, GRAPH<rat_point,rat_segment>& G, bool use_filter)
  390. {
  391.  @<local declarations @>@;
  392.  @<initialization @>@;
  393.  @<sweep @>@;
  394.  @<clean-up @>@;
  395. }
  396. @ During the sweep we use two local types |myPoint| and |mySegment|. 
  397. They are extensions of the LEDA types |rat_point| and |rat_segment| which we use 
  398. to make the program more efficient. A |myPoint| consists of a
  399. |rat_point| plus floating point approximations to the homogeneous coordinates of
  400. the point. Tests on |myPoint|s, e.g. the compare function, are first evaluated 
  401. using the floating point approximations and the exact test is only 
  402. performed if the floating point filter gives insufficient information. 
  403. The details will be described in section ref{geometric primitives}.
  404. A |mySegment| consists of two |myPoint|s $p$ and $q$, the underlying LEDA 
  405. segment |seg|, floating point approximations for the expressions 
  406. $dx = px*qw-qx*pw$ and $dy = py*qw-qy*pw$ which are often used in the program,
  407. and the last node |last_node| of the output graph $G$ lying on the segment
  408. (intially |nil|).
  409. We make both types pointer types to avoid the overhead of copying. 
  410. Note that the objects of both types have multiple occurrences, e.g., 
  411. in |myPoint|s occur in |mySegment|s and also in the X-structure.
  412. We also need to say something about memory management. Our program
  413. allocates storage for |myPoint|s and |mySegment|s. LEDA's memory mangement
  414. feature is used to allocate this storage in big chunks and thus to avoid the
  415. overhead of frequent calls to |malloc|. To free the memory again we use
  416. different strategies for points and segments. A segment (but not its 
  417. constituent points) is deleted when it is removed from the Y-structure. 
  418. All points are collected in a hand-crafted linear list and are deleted 
  419. in section |@<clean-up@>| at the end of |sweep|.
  420. @<global types and declarations@>=
  421. class MyPointRep;
  422. static MyPointRep* first_myPoint = 0;
  423. struct MyPointRep {
  424.   rat_point pt;
  425.   floatf   x;
  426.   floatf   y;
  427.   floatf   w;
  428.   int     count;
  429.   MyPointRep* next;
  430. MyPointRep(const rat_point& p)
  431. { pt = p;
  432.   x = floatf(p.X());
  433.   y = floatf(p.Y());
  434.   w = floatf(p.W());
  435.   count = 0;
  436.   next = first_myPoint;
  437.   first_myPoint = this;
  438. }
  439. LEDA_MEMORY(MyPointRep)
  440. };
  441. typedef MyPointRep* myPoint;
  442. struct MySegmentRep {
  443.   myPoint   start;
  444.   myPoint   end;
  445.   rat_segment seg;
  446.   floatf dx;
  447.   floatf dy;
  448.   node last_node;
  449.  
  450. MySegmentRep(const rat_segment& s)
  451. { start = new MyPointRep(s.start());
  452.   end   = new MyPointRep(s.end());
  453.   seg   = s;
  454.   dx = floatf(s.dx());
  455.   dy = floatf(s.dy());
  456.   last_node = nil;
  457. }
  458.  
  459. MySegmentRep(const myPoint& p) // creates the zero-length segment $(p,p)$
  460. { start = p;
  461.   end = p;
  462.   seg = rat_segment(p->pt,p->pt);
  463.   last_node = nil;
  464. }
  465. LEDA_MEMORY(MySegmentRep)
  466. };
  467. typedef MySegmentRep* mySegment;
  468. @ The programs uses three global variables: 
  469. |Infinity| is a big integer constant that is used as a safe approximation for 
  470. $infty$; it will be initialized to a power of two greater than the maximal 
  471. absolute value of any input coordinate. |p_sweep| is a |myPoint| that defines 
  472. the current sweep position. |use_filter| is a flag that indicates whether 
  473. the floating point filter should be applied, i.e., whether floating point 
  474. computations should be used before doing exact arithmetic.
  475. @<global types and declarations@> +=
  476. integer     Infinity;
  477. myPoint p_sweep;
  478. bool    use_filter;
  479. #if defined(STATISTICS)
  480. int cmp_points_count;
  481. int cmp_points_failed;
  482. int exact_cmp_points_count;
  483. int cmp_segments_count;
  484. int exact_cmp_segments_count;
  485. #endif
  486. @ In the local declarations section of function |sweep| we introduce 
  487. the data types for the event queue (|X_structure|) and for the sweep 
  488. line (|Y_structure|). For the X-structure we use a sorted sequence of 
  489. points with the lexicographic ordering of their coordinates, and for 
  490. the Y-structure a sorted sequence of segments with the linear order 
  491. defined by the sequence intersections of the segments with the sweep line 
  492. at its current position (|p_sweep|) from bottom to top.
  493. The X-structure contains all so far 
  494. known event points right and above of the current sweep line position 
  495. (|p_sweep|), i.e. all start and end points of segments and intersections 
  496. of segments being adjacent in the sweep line. The X-structure associates 
  497. with each event point |p| an item of the Y-structure (|seq_item|) as 
  498. information; if there are only starting segments at |p| the information is 
  499. |nil|, otherwise the information is an item in the Y-structure containing one 
  500. of the segments passing through or ending in |p|. 
  501. Vice versa we associate with each 
  502. segment |s| in the Y-structure that intersects its successor in some point |p| 
  503. the corresponding item |<p,...>| in the X-structure as information.
  504. We call this item the {sl current intersection item} of |s|. If |s| does not 
  505. intersect its successor its current intersection item is |nil|.
  506. Furthermore, we maintain for every point |p| a counter |count| that gives
  507. the number of all segments having |<p,...>| as current intersection item.
  508. We will use this counter to decide whether a point can be removed from the 
  509. X-structure. It can be removed if |count| is zero.
  510. Finally, we store with each segment |s| the last created node
  511. of the output graph |last_node| lying on |s|.
  512. @<local declarations @> =
  513. sortseq<myPoint,seq_item> X_structure;
  514. sortseq<mySegment,seq_item> Y_structure;
  515. @ We now come to the initialization of the data structures. 
  516. We first compute a big integer |Infinity| that can be used as a safe 
  517. approximation for $infty$. We start the sweep at $(-infty,-infty)$. 
  518. At its initial position the sweep line (i.e. the Y-structure)
  519. contains two infinitely long horizontal segments (|lowersentinel| and 
  520. |uppersentinel|) with $y$-coordinates $-infty$ and $+infty$ respectively, 
  521. and the output graph |G| is empty. 
  522. We create for each |rat_segment| in |S| the corresponding |mySegment| 
  523. (reorienting if necessary) and insert its left endpoint together with the 
  524. information |nil| into the $X$-structure. We use the fact that a sorted 
  525. sequence contains at most one item for every key and that a second insert 
  526. operation with the same key only changes the information of the item to make 
  527. the left endpoints of all segments unique. This makes equality tests between 
  528. endpoints of segments much cheaper, since now the |myPoint| pointers can be 
  529. compared directly (using the |==| operator) instead of having to call an 
  530. expensive compare function. 
  531. Finally, we sort all segments according to their left endpoints into
  532. a list |S_Sorted| by calling the LEDA list sorting operation
  533. |S_Sorted.sort(cmp_seg)|. Here |cmp_seg| is a compare function
  534. defined in section ref{geometric primitives}.
  535. @<initialization @> =
  536. #if defined(STATISTICS)
  537. cmp_points_count = 0;
  538. cmp_points_failed = 0;
  539. exact_cmp_points_count = 0;
  540. cmp_segments_count = 0;
  541. exact_cmp_segments_count = 0;
  542. #endif
  543. ::use_filter = use_filter;
  544. /* compute an upper bound |Infinity| for the input coordinates */
  545. Infinity = 1;
  546. rat_segment s;
  547. forall(s,S)
  548.   while ( abs(s.X1()) >= Infinity || abs(s.Y1()) >= Infinity ||
  549.           abs(s.X2()) >= Infinity || abs(s.Y2()) >= Infinity ) 
  550.     Infinity *= 2;
  551. p_sweep =  new MyPointRep(rat_point(-Infinity,-Infinity));
  552. mySegment uppersentinel = 
  553. new MySegmentRep(rat_segment(-Infinity,Infinity,Infinity,Infinity));
  554. mySegment lowersentinel = 
  555. new MySegmentRep(rat_segment(-Infinity,-Infinity,Infinity,-Infinity));
  556. Y_structure.insert(uppersentinel,nil);
  557. Y_structure.insert(lowersentinel,nil);
  558. G.clear();
  559. list<mySegment> S_Sorted;
  560. forall(s,S)
  561.   /* |mySegment|s are always oriented from left to right or (if vertical)
  562.      from bottom to top
  563.    */
  564.   if (s.X1() > s.X2() || (s.X1() == s.X2() && s.Y1() > s.Y2()) )
  565.     s = rat_segment(s.end(),s.start());
  566.   mySegment s1 =  new MySegmentRep(s);
  567.   S_Sorted.append(s1);
  568.   seq_item it  = X_structure.insert(s1->start, nil);
  569.   s1->start = X_structure.key(it);
  570.   s1->start->count++;
  571. }
  572. S_Sorted.sort(cmp_mySeg);
  573. @ To clean everything up we need to remove the two sentinels and all |myPoint|s.
  574. @<clean-up @>=
  575. {
  576.  delete(uppersentinel);
  577.  delete(lowersentinel);
  578.  myPoint p = first_myPoint;
  579.  while (first_myPoint != nil)
  580.  { p = first_myPoint->next;
  581.    delete(first_myPoint);
  582.    first_myPoint = p;
  583.   }
  584. #if defined(STATISTICS)
  585. if (use_filter)
  586. { cout << string("compare points:  %6d / %4d (%5.2f%%)  (%5.2f%% failed)  ",
  587.                  cmp_points_count, exact_cmp_points_count,
  588.                  (100.0*exact_cmp_points_count)/cmp_points_count, 
  589.                  (100.0*cmp_points_failed)/cmp_points_count); 
  590.   newline;
  591.   cout << string("compare segments: %6d / %4d  (%5.2f%%)",
  592.                  cmp_segments_count, exact_cmp_segments_count, 
  593.                  (100.0*exact_cmp_segments_count)/cmp_segments_count); 
  594.   newline;
  595.  }
  596. #endif
  597. }
  598. @ We now come to the heart of procedure sweep: the processing of events. Let
  599. |event = <p,sit>| be the first event in the X-structure and assume 
  600. inductively that our data structure is correct for 
  601. $p_sweep = (p.x,p.y-2epsilon)$. Our goal is to to change |p_sweep| to |p|, 
  602. i.e., move the sweep line across the point |p|. We perform the following 
  603. actions.
  604. We first add a vertex |v| with position |p| to the output graph |G|.
  605. Then, we handle all segments passing through or ending at |p_sweep|. 
  606. Finally, we insert all segments starting
  607. at |p_sweep| into the Y-structure, check for possible intersections
  608. between pairs of segments now adjacent in the Y-structure, and update 
  609. the  X-structure. After having processed the |event| we delete it from 
  610. the X-structure.
  611. @<sweep @> =
  612. while( ! X_structure.empty() )
  613.   seq_item event = X_structure.min();
  614.   seq_item sit = X_structure.inf(event);
  615.   myPoint p = X_structure.key(event);
  616.   node v = G.new_node(p->pt); 
  617.   p_sweep = p;
  618.   @<handle passing and ending segments @>@;
  619.   @<insert starting segments and compute new intersections @>@;
  620.   X_structure.del_item(event);
  621. }
  622. @ label{misuse of compare}
  623. We first handle all segments passing through or ending in point |p|. 
  624. How can we find them?
  625. Recall that the current event is $<p,sit>$ and that $sit not= nil$ iff 
  626. $p in I cup E$. If $sit not= nil$ then $p$ is contained in the segment
  627. associated with |sit|. If $sit = nil$ then $p in St setminus (I cup E)$.
  628. In this case there is at most segment in the Y-structure containing $p$. 
  629. We may determine this segment by looking up the zero-length segment 
  630. |(p->pt,p->pt)| in the Y-structure. We explain in section 
  631. ref{explanation of misuse} why this works.
  632. After the lookup we have either $sit = nil$ and then no segment in the 
  633. Y-structure contains |p| or $sit not= nil$ and then the segment associated 
  634. with $sit$ contains $p$. In the latter case we determine all such segments 
  635. and update the graph $G$ and the Y-structure.
  636. We also declare two items |sit_pred| and |sit_succ| and initialize them to 
  637. |nil|. If the $Y$-structure contains a segment containing |p| then |sit_pred| 
  638. and |sit_succ| will be the set to the predecessor and successor item of the
  639. subsequence of segments containing |p|, otherwise they stay |nil|.
  640.  
  641. @<handle passing and ending segments @> =
  642.   seq_item sit_succ = nil;
  643.   seq_item sit_pred = nil;
  644.   if (sit == nil) 
  645.   { MySegmentRep s(p); // create a zero length segment $s = (p,p)$
  646.     sit = Y_structure.lookup(&s);
  647.    }
  648.                
  649.   if( sit != nil)
  650.   { @<find subsequence of ending or passing segments @>@;
  651.     @<construct edges and delete ending segments @>@;
  652.     @<reverse subsequence of segments passing through |p|@>@;
  653.    }
  654. @ Taking |sit| as an entry point into the Y-structure we determine all segments
  655. incident to |p| from the left or from below. These segments form a subsequence 
  656. of the Y-structure. Let |sit_first| and |sit_last| denote the first and the 
  657. last item of the subsequence and let |sit_pred| be the predecessor of 
  658. |sit_first| and |sit_succ| the successor of |sit_last|. Note that the 
  659. information of all items in this subsequence is equal to the current
  660. event item |event|, except for |sit_last| whose information is either |nil|
  661. or a different item in the X-structure resulting from an intersection
  662. with |sit_succ|. 
  663. Note also that the identification of the subsequence of segments incident to 
  664. $p$ takes constant time per element of the sequence. Moreover, the constant 
  665. is small since the test whether $p$ is incident to a segment involves no 
  666. geometric computation but only equality tests between items.
  667. Note finally that the code is particularly simple due to our sentinel segments:
  668. |sit_first| can never be the first item of the Y-structure and |sit_last|
  669. can never be the last.
  670. @<find subsequence of ending or passing segments @> =
  671.      seq_item sit_last = sit;
  672.      while (Y_structure.inf(sit_last) == event)
  673.          sit_last = Y_structure.succ(sit_last);
  674.      sit_succ = Y_structure.succ(sit_last);
  675.  
  676.      sit_pred = Y_structure.pred(sit);
  677.      while (Y_structure.inf(sit_pred) == event)
  678. sit_pred = Y_structure.pred(sit_pred);
  679.      seq_item sit_first = Y_structure.succ(sit_pred);
  680. @ We can now add edges to the graph |G|. For each segment in the subsequence 
  681. between |sit_first| and |sit_last| inclusive we construct an edge. Let |sit| be 
  682. any such item and let |s| be the segment associated with |sit|. We construct an 
  683. edge connecting |s -> last_node| and |v| and label it with the segment |s|.
  684. We also either delete the item from the Y-structure (if the segment ends at
  685. |p|) or change its information to |nil| (if the segment does not end at |p|) to
  686. reflect the fact that no intersection event is now associated with the 
  687. segment. In the former case we free the storage reserved for the segment.
  688. At the end we have to update variables |sit_first| and |sit_last|
  689. since the corresponding items may have been deleted.
  690. @<construct edges and delete ending segments @> =
  691.      seq_item i1 = sit_pred;
  692.      seq_item i2 = sit_first;
  693.      while (i2 != sit_succ)
  694.      { 
  695.        mySegment s = Y_structure.key(i2);
  696.        G.new_edge(s->last_node,v,s->seg); 
  697.        s->last_node = v;
  698.        if (p == s->end)  // ending segment
  699.           { Y_structure.del_item(i2);
  700.     delete s;
  701.    }
  702.        else
  703.           { //continuing segment
  704.             if (i2 != sit_last) Y_structure.change_inf(i2,nil);
  705.             i1 = i2;
  706.            }
  707.        i2 = Y_structure.succ(i1);
  708.       }
  709.  
  710.       sit_first = Y_structure.succ(sit_pred);
  711.       sit_last = Y_structure.pred(sit_succ);
  712. @ All segments remaining in the subsequence pass through node |v| and moving 
  713. the sweep line through |p_sweep| inverses the order of the segments in the 
  714. subsequence. The subsequence is non-empty iff |sit_last != sit_pred|.
  715. Reversing the subsequence destroys the adjacency of pairs 
  716. (|sit_pred|,|sit_first|) and (|sit_last|,|sit_succ|) in the |Y|-structure 
  717. and hence we have to set the current intersection event of |sit_pred| and 
  718. |sit_last| (i.e. the associated information in the Y-structure) to |nil|,
  719. decrement the corresponding counters, and delete the items from the 
  720. X-structure if the counters are zero now. If the subsequence is empty we 
  721. only need to change the intersection event associated of |sit_pred| to |nil|.
  722. Finally, we reverse the subsequence by calling
  723. |Y_structure.reverse_items(sit_first,sit_last)|.
  724. @<reverse subsequence of segments passing through |p| @> =
  725. seq_item xit = Y_structure.inf(sit_pred);
  726. if (xit != nil)
  727. { if (--X_structure.key(xit)->count == 0) X_structure.del_item(xit);
  728.   Y_structure.change_inf(sit_pred,nil);
  729.  }
  730. if (sit_last != sit_pred)
  731. { xit = Y_structure.inf(sit_last);
  732.   if (xit != nil)
  733.   { if (--X_structure.key(xit)->count == 0) X_structure.del_item(xit);
  734.     Y_structure.change_inf(sit_last,nil);
  735.    }
  736.   Y_structure.reverse_items(sit_first,sit_last);
  737. }
  738. @ The last step in handling the event point |p| is to insert all segments 
  739. starting at |p| into the |Y|-structure and to test the new pairs of adjacent
  740. items (|sit_pred|,...) and (...,|sit_succ|) for possible intersections. If
  741. there were no segments passing through or ending in |p| then the items 
  742. |sit_succ| and |sit_pred| are still |nil|  and we have to compute them now.
  743. We use the sorted list |S_Sorted| to find all segments to be 
  744. inserted. As long as the first segment |seg| in |S_Sorted| starts at point |p| 
  745. we remove it from the list, insert it into the |Y|-structure, add its right 
  746. endpoint to the |X|-structure, and set |seg -> last_node| to |v|. If the 
  747. segment has length zero we simply discard it and if |sit_succ| and |sit_pred| 
  748. are still undefined (|nil|) then we use the first inserted segment to define 
  749. them. In this case, we also have to change the possible current intersection
  750. event of |sit_pred| to |nil| since it is no longer adjacent to |sit_succ|.
  751. If all segments starting in |p| have length zero then |sit_succ| and 
  752. |sit_pred| remain undefined. 
  753. We need to say more clearly how to insert a segment |s| into the |Y|-structure.
  754. If the |Y|-structure contains no segment with the same underlying line then we
  755. simply add the segment. Otherwise, let $s'$ be the segment in the |Y|-structure
  756. with the same underlying line. We replace |s| by $s'$ if $s'$ extends further 
  757. to the right than $s$ and do nothing otherwise.
  758. After having inserted all segments starting at |p|, we test whether |sit_succ| 
  759. (|sit_pred|) intersects its predecessor (successor) in the |Y|-structure.
  760. @<insert starting segments and compute new intersections@> =
  761. while (!S_Sorted.empty() && p == S_Sorted.head()->start)
  762.   mySegment Seg = S_Sorted.pop();
  763.   /* first insert the right endpoint of |Seg| into the X-structure */
  764.   seq_item end_it= X_structure.insert(Seg->end,nil);
  765.   Seg->end = X_structure.key(end_it);
  766.   Seg->end->count++;
  767.   /* note that the following test uses the fact that two endpoints are equal 
  768.      if an only if the corresponding pointer values (|myPoint|s) are equal
  769.    */
  770.   if (Seg->start == Seg->end)   // Seg has length  zero, nothing to do
  771.   { delete Seg;
  772.     continue;
  773.    }
  774.   sit = Y_structure.locate(Seg);
  775.   if (compare(Seg, Y_structure.key(sit)) != 0) 
  776.    { /* |Seg| is not collinear with the segment associated with |sit|. We
  777.         simply insert |Seg| into the Y-structure 
  778.       */
  779.      sit = Y_structure.insert_at(sit,Seg,nil); 
  780.      Seg->last_node = v;
  781.     }
  782.   else 
  783.    { /* |Seg| is collinear with the segment associated with |sit|. If |Seg| is 
  784.         longer then we use |Seg| and otherwise we do nothing.
  785.        */
  786.      mySegment Seg_old = Y_structure.key(sit);
  787.      if (compare(Seg->end, Seg_old->end) > 0)
  788.      { /* |Seg| extends further to the right or above 
  789.           replace |Seg_old| by |Seg|.  */
  790.        Seg_old->seg = Seg->seg;
  791.        Seg_old->end = Seg->end;
  792.       }
  793.      delete Seg;   // not needed anymore
  794.     }
  795.    X_structure.change_inf(end_it,sit);
  796.    if (sit_succ == nil)
  797.    { sit_succ = Y_structure.succ(sit);
  798.      sit_pred = Y_structure.pred(sit);
  799.      /* |sit_pred| is no longer adjacent to |sit_succ| we have to
  800.         change its current intersection event to |nil| and delete
  801.         the corresponding item in the X-structure if necessary
  802.       */
  803.      seq_item xit = Y_structure.inf(sit_pred);
  804.      if (xit != nil)
  805.      { if (--X_structure.key(xit)->count == 0) X_structure.del_item(xit);
  806.        Y_structure.change_inf(sit_pred,nil);
  807.       }
  808.     }
  809. }
  810. /* compute possible intersections */
  811. if (sit_succ != nil)  // |v| is an isolated vertex otherwise
  812. {
  813.   compute_intersection(X_structure,Y_structure,sit_pred);
  814.   sit = Y_structure.pred(sit_succ);
  815.   if (sit != sit_pred) 
  816.     compute_intersection(X_structure,Y_structure,sit);
  817.  }
  818. @* Geometric Primitives.
  819. label{geometric primitives}
  820. It remains to define the geometric primitives used in the implementation. We
  821. need four:
  822. begin{itemize}
  823. item
  824.   a compare function for |myPoint|s which orders points according 
  825.   to the lexicographic ordering of their coordinates. It defines the linear 
  826.   order used in the X-structure.
  827. item
  828.   a compare-function for |mySegment|s which given two segments intersecting the
  829.   sweep line $L$ determines the order of the intersections on $L$. It defines 
  830.   the linear order used in the Y-structure.
  831. item
  832.   a second compare function |cmp_mySeg| for |mySegment|s which orders segments
  833.   according to the order of their left endpoint. It is used to sort the list 
  834.   |S_Sorted| in the beginning.
  835. item
  836.   a function |compute_intersection| that decides whether two segments intersect
  837.   and if so whether the intersection is to the right of the sweep line. If
  838.   both tests are positive it also makes the required changes to the $X$- and
  839.   $Y$-structure.
  840. end{itemize}
  841. We define the compare functions for |myPoint|s and |mySegment|s in two steps.
  842. We first write two function templates |cmp_points| and |cmp_segments|
  843. for comparing points and segments given by their homogenous coordinates,
  844. independently from the actual (numerical) type of the coordinates.
  845. These templates can be used to compare points and segments with coordinates 
  846. of any integer type |int_type| that supports addition, subtraction, 
  847. multiplication, and a special sign function |Sign(x)| that returns
  848. $+1$ if $x > 0$, $0$ if $x = 0$, $-1$ if $x < 0$, and a special integer 
  849. value |NO_IDEA| if the test cannot be performed in a conclusive way.
  850. We start with writing a compare function |cmp_points(x1,y1,w1,x2,y2,w2)|
  851. that compares two points with homogeneous coordinates $(x_1,y_1,w_1)$ and 
  852. $(x_2,y_2,w_2)$. A point $(x_1,y_1,w_1)$ precedes a point $(x_2,y_2,w_2)$ 
  853. if the pair $(x_1/w_1,y_1/w_1)$ lexicographically precedes the pair 
  854. $(x_2/w_2,y_2/w_2)$, i.e., if ($x_1w_2 > x_2w_1$) or ($x_1w_2 = x_2w_1$ and 
  855. $y_1w_2 > y_2w_1$).
  856. @<geometric primitives @> =
  857. /*
  858. template <class int_type> inline
  859. int cmp_points(const int_type& x1, const int_type& y1, const int_type& w1,
  860.                const int_type& x2, const int_type& y2, const int_type& w2)
  861.   int s = Sign(x1*w2-x2*w1);
  862.   return (s != 0) ? s : Sign(y1*w2-y2*w1);
  863.  }
  864. */
  865. inline int cmp_points(const integer& x1, const integer& y1, const integer& w1,
  866.                       const integer& x2, const integer& y2, const integer& w2)
  867.   int s1 = sign(x1) * sign(w2);
  868.   int s2 = sign(x2) * sign(w1);
  869.   if (s1 > s2) return +1;
  870.   if (s1 < s2) return -1;
  871.   int l1 = x1.length() + w2.length();
  872.   int l2 = x2.length() + w1.length();
  873.   if (l1 > l2+1) return   s1;
  874.   if (l2 > l1+1) return  -s1;
  875. /*
  876.   int s = cmp_products(x1,w2,x2,w1);
  877.   return (s != 0) ? s : cmp_products(y1,w2,y2,w1);
  878. */
  879.   int s = compare(x1*w2,x2*w1);
  880.   return (s != 0) ? s : compare(y1*w2,y2*w1);
  881.  }
  882. inline int cmp_points(const floatf& x1, const floatf& y1, const floatf& w1,
  883.                       const floatf& x2, const floatf& y2, const floatf& w2)
  884.   int s = Sign(x1*w2-x2*w1);
  885.   return (s != 0) ? s : Sign(y1*w2-y2*w1);
  886.  }
  887. inline int cmp_points(const double& x1, const double& y1, const double& w1,
  888.                       const double& x2, const double& y2, const double& w2)
  889.   int s = Sign(x1*w2-x2*w1);
  890.   return (s != 0) ? s : Sign(y1*w2-y2*w1);
  891.  }
  892. @ Next we write the compare function |cmp_segments| for segments.
  893. A segment is stored as the pair of its endpoints and a point is stored
  894. by its homogeneous coordinates, i.e., as a triple $(X,Y,W)$ of integers (type 
  895. |integer|). The $x$- and $y$-coordinates of the point are $X/W$ and $Y/W$ 
  896. respectively. 
  897. |cmp_segments| takes the coordinates of two segments $s_1$ and $s_2$ 
  898. intersecting the sweep line |L|.
  899. We assume that both segments have non-zero length and treat the case that one of
  900. them has zero length in the next section.
  901. If both segments have the same underlying line then we return 0. 
  902. So let us assume that the underlying lines are different. Let |l| denote the
  903. vertical line through |p_sweep|. Only one of the segments can be vertical. If
  904. $s_1$ is vertical and hence intersects |L| in $(x_sweep,y_sweep+epsilon)$ 
  905. then $s_1$ is before $s_2$ iff |p_sweep| is below $lcap s2$. If $s_2$ is
  906. vertical then $s_1$ is before $s_2$ iff $lcap s1$ is not above |p_sweep|.
  907. Assume now that neither $s_1$ nor $s_2$ is vertical. If $lcap s1$ and 
  908. $lcap s2$ are distinct then $s_1$ is before $s_2$ iff $lcap s1$ 
  909. is below $lcap s2$. If $lcap s1$ and $lcap s2$ are identical and not above
  910. |p_sweep| then $s_1$ is before $s_2$ iff $s_1$ has the smaller slope. Finally,
  911. if the intersections are identical and above |p_sweep| then $s_1$ is before
  912. $s_2$ iff $s_1$ has the larger slope. 
  913. @<geometric primitives @> +=
  914. template <class int_type>
  915. int cmp_segments( const int_type& px,  const int_type& py,  const int_type& pw,
  916.                   const int_type& spx, const int_type& spy, const int_type& spw,
  917.                   const int_type& sqx, const int_type& sqy, const int_type& sqw,
  918.                   const int_type& rx,  const int_type& ry,  const int_type& rw,
  919.                   const int_type& dx,  const int_type& dy,
  920.                   const int_type& sdx, const int_type& sdy)
  921. {
  922. @;
  923.   /*
  924.     We first test whether the underlying lines are identical. The lines are
  925.     identical if the three slopes $dy/dx$, $sdy/sdx$, and $mdy/mdx$ are equal
  926.   */
  927. @;
  928.   
  929.   int_type T1 = dy*sdx - sdy*dx;
  930.   int sign1 = Sign(T1);
  931.   if (sign1 == 0 || sign1 == NO_IDEA)
  932.   { int_type mdx = sqx*pw - px*sqw;
  933.     int_type mdy = sqy*pw - py*sqw;
  934.     int sign2 = Sign(dy*mdx - mdy*dx);
  935.     if (sign2 == 0 || sign2 == NO_IDEA)
  936.     { int sign3 = Sign(sdy*mdx - mdy*sdx);
  937.       if (sign3 == 0 || sign3 == NO_IDEA)
  938.       return (sign1 == 0 && sign2 == 0 && sign3 == 0)  ? 0 : NO_IDEA;
  939.      }
  940.    }
  941. @;
  942.    /* The underlying lines are different; in particular, at most one of the
  943.       lines is vertical. We first deal with the cases that one of the lines 
  944.       is vertical. A segment $(p,q)$ is vertical iff $px*qw-qx*pw$ is equal 
  945.       to zero. Since |dx| is an optimal floating point approximation
  946.       of this integer value, a segment is vertical iff its |dx|-value is zero.
  947.     */
  948. @;
  949.     if (dx == 0)
  950.        { /* |dx| = 0, i.e., |s1| is vertical and |s2|  is not vertical; 
  951.             $l cap s2$ is above |p_sweep| iff 
  952.             $(spy/spw + sdy/sdx(rx/rw - spx/spw) -ry/rw) > 0$; 
  953.             in this case we return $-1$ 
  954.           */
  955.           int i = Sign((spy*sdx - spx*sdy)*rw + (sdy*rx - ry*sdx)*spw);
  956.           if (i==NO_IDEA) return NO_IDEA;
  957.           return (i <= 0) ? 1 : -1;
  958.         }
  959. @;
  960.     if (sdx == 0)
  961.        { /* $sdx = 0$, i.e., |s2| is vertical but |s1| is not vertical; 
  962.             we return -1 if
  963.             $l cap s1$ is below or equal to |p_sweep| iff 
  964.             $(py/pw + dy/dx(rx/rw - px/pw)-ry/rw) leq 0$.
  965.           */
  966.          int i = Sign((py*dx - px*dy) * rw + (dy*rx - ry*dx) * pw);
  967.          if (i==NO_IDEA) return NO_IDEA;
  968.          return (i <= 0) ? -1 : 1;
  969.        }
  970. @;
  971.   /* Neither |s1| nor |s2| is vertical. We compare $l cap s1$ and $ l cap s2$.
  972.      We have $$ y(l cap s1) -y(l cap s2) = 
  973.      frac{py}{pw} +frac{dy}{dx}(frac{rx}{rw} -frac{px}{pw}) -frac{spy}{spw}
  974.      - frac{sdy}{sdx}(frac{rx}{rw} - frac{spx}{spw}). $$ 
  975.      If the difference is non-zero then we return its sign. If the difference is
  976.      zero then we return $-1$ iff the common intersection is not above 
  977.      |p_sweep| and $s1$ has the smaller slope or the intersection is above 
  978.      |p_sweep| and $s1$ has the larger slope.
  979.   */
  980. @;
  981.   int_type T2 = sdx*spw*(py*dx*rw+dy*(rx*pw-px*rw)) 
  982.                 - dx*pw*(spy*sdx*rw+sdy*(rx*spw-spx*rw));
  983.   int sign2 = Sign(T2);
  984.   if (sign2 == NO_IDEA) return NO_IDEA;
  985.   if (sign2 != 0) return sign2;
  986. @;
  987.   /* Now we know that the difference is zero, i.e., |s1| and |s2| 
  988.      intersect in a point $I$. We compare slopes:\
  989.      |s1| has larger slope than |s2| iff |T1*dxs*dx > 0|; 
  990.      note that orienting the lines from left to right makes all |dx| 
  991.      values non-negative , i.e., 
  992.      |s1| has larger slope than |s2| iff |sign(T1) = 1|
  993.    */
  994.   int_type T3 = (py*dx - px*dy) * rw + (dy*rx - ry*dx) * pw;
  995.   /* The common intersection $I$ is above |p_sweep| iff $T3*rw*dx*pw > 0$.
  996.      In this case we return |-sign(T1)| and |sign(T1)| otherwise.
  997.      Note that all |dx| and |w| values are non-negative
  998.      i.e., |sign(T3*rw*dx*pw) = sign(T3)|
  999.    */
  1000.   int sign3 = Sign(T3);
  1001.   if (sign3 == NO_IDEA) return NO_IDEA;
  1002.   return (sign3 <= 0) ? sign1 : -sign1;
  1003. }
  1004. @ Finally, we define the compare functions for |myPoint|s and |mySegment|s
  1005. by first calling |cmp_points| and |cmp_segments| on the floating point
  1006. filter coordinates (of type |floatf|) of the corresponding points and segments.
  1007. In the case that these calls do not return a reliable result (i.e. return
  1008. |NO_IDEA|) we call them again with the exact coordinates (of type |integer|).
  1009. @<geometric primitives @> +=
  1010. inline int compare(const myPoint& a, const myPoint& b)
  1011.   /* floating point filter version for |myPoint|s */
  1012. #if defined(STATISTICS)
  1013.   cmp_points_count++;
  1014. #endif
  1015.  int c = NO_IDEA;
  1016.  /* if not explicitely turned off we first use floating point arithmetic */
  1017.  if (use_filter)
  1018.    c = cmp_points( a->x, a->y, a->w, b->x, b->y, b->w);
  1019.  /* if the floating point computation is not reliable, i.e., the result 
  1020.     is |NO_IDEA| we use exact arithmetic (|integer|) 
  1021.   */
  1022.  if (c == NO_IDEA) 
  1023.  {
  1024.    c = cmp_points(a->pt.X(),a->pt.Y(),a->pt.W(), b->pt.X(),b->pt.Y(),b->pt.W());
  1025. #if defined(STATISTICS)
  1026.   exact_cmp_points_count++;
  1027.   if (cmp_points(double(a->x),double(a->y),double(a->w),
  1028.                  double(b->x),double(b->y),double(b->w)) != c) 
  1029.      cmp_points_failed++;
  1030. #endif
  1031.   }
  1032.  return c;
  1033. }
  1034.  
  1035. inline int compare(const mySegment& s1,const mySegment& s2)
  1036.   int c = NO_IDEA;
  1037.   /* if not explicitely turned off we first try the 
  1038.      floating point computation 
  1039.    */
  1040. #if defined(STATISTICS)
  1041. cmp_segments_count++;
  1042. #endif
  1043.   if (use_filter)
  1044.       c =  cmp_segments(s1->start->x, s1->start->y, s1->start->w,
  1045.                         s2->start->x, s2->start->y, s2->start->w,
  1046.                         s2->end->x,   s2->end->y,   s2->end->w,
  1047.                         p_sweep->x,   p_sweep->y,   p_sweep->w,
  1048.                         s1->dx, s1->dy, s2->dx, s2->dy);
  1049.     
  1050.   /* If the result is not reliable  we call the exact compare 
  1051.      for the underlying |rat_segment|s.
  1052.    */
  1053.   if (c == NO_IDEA)
  1054.   { c = cmp_segments(s1->seg.X1(), s1->seg.Y1(), s1->seg.W1(),
  1055.                      s2->seg.X1(), s2->seg.Y1(), s2->seg.W1(), 
  1056.                      s2->seg.X2(), s2->seg.Y2(), s2->seg.W2(),
  1057.                      p_sweep->pt.X(), p_sweep->pt.Y(), p_sweep->pt.W(),
  1058.                      s1->seg.dx(),s1->seg.dy(), s2->seg.dx(),s2->seg.dy());
  1059. #if defined(STATISTICS)
  1060.     exact_cmp_segments_count++;
  1061. #endif
  1062.    }
  1063.   return c;
  1064. }
  1065. @ For the initialization of the list |S_Sorted| we need a second compare 
  1066. function |cmp_mySeg| for |mySegment|s. It simply compares the left endpoints.
  1067. @<geometric ...@>+=
  1068. int cmp_mySeg(const mySegment& s1, const mySegment& s2) 
  1069.   int c = NO_IDEA;
  1070.   if (use_filter) // floating point compare
  1071.      c = cmp_points(s1->start->x, s1->start->y, s1->start->w,
  1072.                     s2->start->x, s2->start->y, s2->start->w);
  1073.   
  1074.   if (c == NO_IDEA) // exact compare
  1075.      c = cmp_points(s1->seg.X1(),s1->seg.Y1(),s1->seg.W1(),
  1076.                     s2->seg.X1(),s2->seg.Y1(),s2->seg.W1());
  1077.   return c;
  1078. }
  1079. @ label{explanation of misuse}
  1080. What does compare do when one of the segments, say |s1|, has both endpoints 
  1081. equal to |p_sweep| and the Y-structure contains 
  1082. at most one segment containing |p_sweep|. That's exactly 
  1083. the situation in section ref{misuse of compare}. When |s2| 
  1084. contains |p_sweep| the underlying lines are found identical and 
  1085. compare returns 0. When |s2| does not contain 
  1086. |p_sweep| then the underlying lines are declared different. 
  1087. Also |s1| is declared vertical and
  1088. |s2| is not vertical since it would otherwise contain |p_sweep|. 
  1089. We now compare
  1090. $ l cap s2$ and |p_sweep| and return the result. We conclude that the call
  1091. |Y_structure.locate(s)| where $s$ is the zero-length segment |(p->pt,p->pt)| 
  1092. in section ref{misuse of compare} has the desired effect.
  1093. @ Finally, we define a function |compute_intersection| that takes an item
  1094. |sit0| of the Y-structure and determines whether the segment associated with
  1095. |sit0| intersects the segment associated with the successor of |sit0|
  1096. right or above of the sweep line. If so it updates the X- and the Y-structure.
  1097. The function first tests whether the underlying straight lines intersect right 
  1098. or above of the sweep line by comparing their slopes. This test is performed
  1099. with floating point arithmetic and repeated with exact arithmetic if the
  1100. floating point test gives no reliable result.  If the segments do intersect
  1101. right or above of the sweep line it is checked whether the point of 
  1102. intersection lies on both segments, i.e., is not larger than the endpoints of 
  1103. the segments.
  1104. @<geometric ...@>+=
  1105. void compute_intersection(sortseq<myPoint,seq_item>& X_structure,
  1106.                           sortseq<mySegment,seq_item>& Y_structure, 
  1107.                           seq_item sit0)
  1108.   seq_item  sit1 = Y_structure.succ(sit0);
  1109.   mySegment seg0 = Y_structure.key(sit0);
  1110.   mySegment seg1 = Y_structure.key(sit1);
  1111.   /* |seg1| is the successor of |seg0| in the Y-structure, hence, 
  1112.      the underlying lines intersect right or above of the sweep line 
  1113.      iff the slope of |seg0| is larger than the slope of |seg1|. 
  1114.    */
  1115.   if (use_filter)
  1116.   { int i = Sign(seg0->dy * seg1->dx - seg1->dy * seg0->dx);
  1117.     if (i == -1 || i == 0) return; /* $slope(s0)leq slope(s1)$ */
  1118.    }
  1119.   rat_segment s0 = seg0->seg;
  1120.   rat_segment s1 = seg1->seg;
  1121.   integer w = s0.dy()*s1.dx() - s1.dy()*s0.dx();
  1122.   if (sign(w) > 0)   // $slope(s0) > slope(s1)$
  1123.   {
  1124.     integer c1 = s0.X2()*s0.Y1() - s0.X1()*s0.Y2();
  1125.     integer c2 = s1.X2()*s1.Y1() - s1.X1()*s1.Y2();
  1126.     /* The underlying lines intersect in a point right or above of the 
  1127.        sweep line. We still have to test whether it lies on both segments.
  1128.      */
  1129.     integer x = c2*s0.dx()-c1*s1.dx();
  1130.     integer d0 = x*s0.W2() - s0.X2()*w;
  1131.     if (sign(d0) > 0) return;
  1132.     if (x*s1.W2() > s1.X2()*w) return;
  1133.     integer y = c2*s0.dy()-c1*s1.dy();
  1134.     if (sign(d0)==0 && y*s0.W2() > s0.Y2()*w) return;
  1135.     myPoint Q = new MyPointRep(rat_point(x,y,w));
  1136.     seq_item xit = X_structure.insert(Q,sit0);
  1137.     X_structure.key(xit)->count++;
  1138.     Y_structure.change_inf(sit0,xit);
  1139.   }
  1140. }
  1141.  
  1142. @* A Floating Point Filter. 
  1143. label{floatf}
  1144. The type |floatf| provides a clean and efficient way to approximately
  1145. compute with large integers. Consider an expression |E| with integer
  1146. operands and operators $+,-$, and $*$, and suppose that we want
  1147. to determine the sign of |E|. In general, the integer arithmetic
  1148. provided by our machines does not suffice to evaluate |E| since intermediate
  1149. results might overflow. Resorting to arbitrary precision integer
  1150. arithmetic is a costly process. An alternative is to evaluate the 
  1151. expression using floating point arithmetic, i.e., to convert the
  1152. operands to doubles and to use floating-point addition, subtraction,
  1153. and multiplication. Of course, only an approximation $tilde{E}$ of
  1154. the true value |E|footnote{We misuse notation and use |E| to denote the
  1155. expression and its value.} is computed. However, $tilde{E}$ might still be
  1156. able to tell us something about the sign of |E|. If $tilde{E}$ is far
  1157. away from zero (the forward error analysis carried out in the next
  1158. section gives a precise meaning to "far away") then the 
  1159. signs of $tilde{E}$ and |E| 
  1160. agree and if $tilde{E}$ is zero then we may be able to conclude under
  1161. certain circimstances that |E| is zero. Again, forward error analysis
  1162. can be used to say what `certain circumstances' are. The type |floatf|
  1163. encapsulates this kind of approximate integer arithmetic. Any
  1164. integer (= object of type |integer|) can be converted to a |floatf|,
  1165. |floatf|s can be added, subtracted, multiplied, and their sign
  1166. can be computed: for any |floatf| $x$ the function |Sign(x)| returns 
  1167. either the sign of $x$ ($-1$ if $x < 0$, $0$ if $x = 0$, and $+1$ 
  1168. if $x > 0$) or the special value |NO_IDEA|.
  1169. If |x| approximates |X|, i.e., |X| is the integer value abtained by an 
  1170. exact computation, then |Sign(x) != NO_IDEA| implies that |Sign(x)| 
  1171. is actually the sign of $X$ if
  1172. |Sign(x) = NO_IDEA| then no claim is made about the sign of |X|.\
  1173. smallskip
  1174. underline{Declaration}\
  1175. bigskip
  1176. |floatf x| declares |x| as a variable of type |floatf|\
  1177. smallskip
  1178. underline{Operations}\
  1179. parbox{8.5cm}{|floatf floatf(integer i)|} 
  1180. parbox[t]{6.5cm}{converts |i| to a float}\
  1181. parbox{8.5cm}{|floatf +(floatf a, floatf b)|}
  1182. parbox[t]{6.5cm}{Addition}\
  1183. parbox{8.5cm}{|floatf -(floatf a, floatf b)|}
  1184. parbox[t]{6.5cm}{Subtraction}\
  1185. parbox{8.5cm}{|floatf *(floatf a, floatf b)|}
  1186. parbox[t]{6.5cm}{Multiplication}
  1187. parbox{8.5cm}{|{-1,0,+1,NO_IDEA} Sign(floatf x)|}
  1188. parbox[t]{6.5cm}{as described above}\
  1189. A |floatf| is represented by a double (its value) and an error bound.
  1190. An operation on |floatf|s performs the corresponding operation on
  1191. the values and also computes the error bound for the result. For
  1192. this reason the cost of a |floatf| operation is about four times
  1193. the cost of the corresponding operation on
  1194. doubles. Rules ref{first rule} to ref{sixth rule} below are used
  1195. to compute the error bounds.
  1196. @ Floating Point Numbers.
  1197. A {em floating point number} is a number of the form
  1198. [ a = mcdot 2^e,]
  1199. where $ein [e_{min}.. e_{max}]$ is
  1200. the {em exponent}, and $m$ is the {em mantissa}. The mantissa is a rational
  1201. number of the form
  1202. [m = vcdot sum_{1leq ileq l} m_icdot 2^{-i},]
  1203. where $vin { -1,1}$ is the sign, $l$ is the {em mantissa length}, and the
  1204. $m_i$'s are the {em digits} of the mantissa. We have $m_iin {0,1}$ and 
  1205. either $m = 0$ or $m_1 = 1$. One also says that the mantissa is
  1206. {em normalized}. We also assume that $lleq e_{max}$. The latter 
  1207. assumption implies that all integers whose absolute value is less than
  1208. $2^{l+1}$ can be presented as floating point numbers.
  1209. Let $cal{F}$ denote the set of all floating point numbers; the set $cal{F}$ 
  1210. clearly depends on the exponent range $[e_{min} .. e_{max}]$
  1211. and the mantissa length $l$. In our examples, we use $l = 53$,
  1212. $e_{min} = -1022$, and $e_{max} = 1023$.
  1213. This choice corresponds to the  IEEE double precision floating point standard.
  1214. The absolute values of all non-zero floating point numbers lie between 
  1215. $min_abs = 2^{e_{min}-1}$ and $max_abs = (1-2^{-l}) 2^{e_{max}}$. 
  1216. Call a real number 
  1217. {em representable} if it is either 0 or its absolute value lies in the
  1218. interval $[min_abs, max_abs]$ and let the size |size(a)| of a real
  1219. number |a| be the smallest power of two larger than its absolute 
  1220. value,i.e.,
  1221. [ size(a) = left {
  1222.              begin{array}{rl}
  1223.      0 & mbox{ if } a=0\
  1224.      2^{lceil logabs{a} rceil} & mbox{ if }aneq 0
  1225.      end{array}
  1226.      right.
  1227. ]
  1228. Then $size(a)/2leq abs{a}leq size(a)$. If a number |a| is 
  1229. representable then there is a floating point number $fl(a)in cal{F}$
  1230. such that
  1231. begin{eqnarray} label{fl}
  1232. abs{a - fl(a)}leq 1/2cdot 2^{-l}cdot size(a)leq 2^{-l}abs{a}
  1233. end{eqnarray}
  1234. The number $fl(a)$ can be obtained from $a$ by rounding in the $l$-th most
  1235. significant position. We call $fl(a)$ a {em floating point approximation} of
  1236. $a$ and use $eps$ to denote $2^{-l}$. Note that $fl(a)$ is a floating point
  1237. number that is closest to $a$.
  1238. The set $cal{F}$ of floating point numbers is not closed under the arithmetic 
  1239. operations addition, subtraction, and multiplication, i.e., if $f_1$ and 
  1240. $f_2$ are floating point numbers and $op$ is any one of the arithmetic 
  1241. operations then $f_1 op f_2$ does not necessarily belong to $cal{F}$. The
  1242. machine implementation of the operation (we use $oplus, ominus$, and
  1243. $odot$ to denote the implementation of $+, -$, and $cdot$ respectively) 
  1244. therefore returns a floating point approximation of the exact result, 
  1245. i.e., a number $tilde{f}$ such that
  1246. begin{eqnarray} label{op}
  1247. abs{tilde{f} - f_1 op f_2}leq 1/2cdot epscdot size(f_1op f_2) 
  1248. leq epscdot abs{f_1 op f_2}
  1249. end{eqnarray}
  1250. or equivalently
  1251. begin{eqnarray*} tilde{f} = (1+epsilon)cdot(f_1 op f_2)end{eqnarray*}
  1252. for some $epsilon$ with $abs{epsilon}leq eps$.
  1253. Note that if $f_1 op f_2$ is a floating point number then $tilde{f} = f_1 op f_2$ 
  1254. since the computed result is the floating point number closest to the exact
  1255. result. In particular, if $f_1$ and $f_2$ are both powers of 2 then
  1256. $f_1odot f_2 = f_1cdot f_2$ and if $f_1 = f_2$ and $f_1$ is a
  1257. power of 2 then $f_1oplus f_2 = f_1 + f_2 = 2cdot f_1$. The floating point
  1258. operations $oplus$ and $odot$ also satisfy a monotonicity property, namely,
  1259. if $f_1leq g_1$ and $f_2leq g_2$ then $f_1oplus f_2 leq g_1oplus g_2$ and
  1260. $f_1odot f_2leq g_1odot g_2$. For the second inequality we also need
  1261. $f_1geq 0$ and $f_2geq 0$.
  1262. We next turn to expression evaluation. Let $E$ be an arithmetic expression,
  1263. e.g., $E = acdot b - ccdot d$. When we evaluate $E$ using floating point 
  1264. arithmetic we obtain $tilde{E} = aodot bominus codot d$. What is the relationship
  1265. between the exact value
  1266. $E$ and the computed value $tilde{E}$?
  1267. We have
  1268. begin{eqnarray*}
  1269. aodot b&=&(1+epsilon_1)cdot acdot b\
  1270. codot d&=&(1+epsilon_2)cdot ccdot d\
  1271. aodot bominus codot d&=&(1+epsilon_3)(aodot b - codot d)
  1272. end{eqnarray*}
  1273. for some constants $epsilon_1$, $epsilon_2$, $epsilon_3$ with 
  1274. $abs{epsilon_i}leq eps$ and hence
  1275. begin{eqnarray*}
  1276. tilde{E}&=&(acdot bcdot (1+epsilon_1) - ccdot dcdot (1+epsilon_2))(1+epsilon_3)\
  1277. &=&E+Ecdot epsilon_3 + (acdot bcdot epsilon_1 - ccdot dcdot epsilon_2)(1+epsilon_3).
  1278. end{eqnarray*}
  1279. The error
  1280. [tilde{E} - E = Ecdot epsilon_3 + acdot bcdot epsilon_1 - 
  1281.                   ccdot dcdot epsilon_2 +(acdot bcdot epsilon_1 - 
  1282.                   ccdot dcdot epsilon_2)cdot epsilon_3]
  1283. is therefore essentially the sum of the errors introduced by considering the 
  1284. three operations individually. In addition, there is a `high-order' term.
  1285. One can drop the higher-order term by expressing the error in terms of upper
  1286. bounds on the inputs of an expression rather than the actual input values
  1287. themselves. This leads to weaker but more managable error bounds. 
  1288. @ A Floating Point Filter.
  1289. Throughout this section |E| denotes an expression involving real operands
  1290. and the arithmetic operations addition, subtraction, and multiplication. 
  1291. We use |E| to also denote the value of the expression. 
  1292. We assume that the operands
  1293. and more generally the values of all subexpressions to be representable
  1294. and use $tilde(E)$ to denote the value of the expression when
  1295. evaluated with floating point arithmetic, i.e., first all operands
  1296. are replaced by their floating point approximations and then all 
  1297. operations by their floating point counterparts. Our goal is to derive an
  1298. easily computed bound for the difference between the computed
  1299. value $tilde{E}$ and the exact value |E|.
  1300. To this end we define for every expression |E| its {em measure} $mes(E)$
  1301. and its {em index} $ind(E)$. The 
  1302. measure $mes(E)$ is a power of two which bounds the size of $E$
  1303. and $tilde{E}$ from above, i.e.,
  1304. begin{eqnarray} label{M}
  1305. size(E)leq mes(E) mbox{ and } size(tilde{E})leq mes(E)
  1306. end{eqnarray} 
  1307. The index  $ind(E)$ bounds the difference of the computed result $tilde{E}$
  1308. and the exact value $E$ as a multiple of $epscdot mes(E)$, i.e.,
  1309. begin{eqnarray} label{I}
  1310. abs{tilde{E} - E} leq ind(E)cdot eps cdot mes(E).
  1311. end{eqnarray}
  1312. The crucial observation is now that both quantities are easily computed 
  1313. inductively. Here are the rules:
  1314. If |E = a|, where |a| is a representable real number, then
  1315. begin{equation} mes(E) = size(a) label{first rule}
  1316. end{equation}
  1317. and 
  1318. begin{equation} ind(E) = left {
  1319.                  begin{array}{rl}
  1320.  0 & mbox{ if }ain cal{F}\
  1321.  1/2 & mbox{ otherwise }
  1322.  end{array} right.
  1323.  label{second rule} end{equation}
  1324. if $E = E_1 pm E_2$ then
  1325. begin{eqnarray}
  1326. mes(E)&=&2cdot max(mes(E_1),mes(E_2)) label{third rule}
  1327. end{eqnarray}
  1328. and
  1329. begin{eqnarray}
  1330. ind(E)&=&(1 + ind(E_1) + ind(E_2))/2, label{fourth rule}
  1331. end{eqnarray}
  1332. and if $E = E_1cdot E_2$ then
  1333. begin{eqnarray}
  1334. mes(E)&=&mes(E_1)cdot mes(E_2) label{fifth rule}
  1335. end{eqnarray}
  1336. and
  1337. begin{eqnarray}
  1338. ind(E)&=&1/2 + ind(E_1) + ind(E_2). label{sixth rule}
  1339. end{eqnarray}
  1340. begin{lemma}
  1341. Let |E| be an expression with real operands and assume that the
  1342. values of all subexpressions of |E| are representable. Then rules 
  1343. (ref{first rule}) to (ref{sixth rule}) compute quantities $mes(E)$
  1344. and $ind(E)$ satisfying (ref{M}) and (ref{I}).
  1345. end{lemma}
  1346. begin{proof}:
  1347. If |E = a|, where |a| is a real, then $tilde{E} = fl(a)$.
  1348. Clearly, $abs{a}leq size(a)$ and $abs{fl(a)}leq size(a)$ (note 
  1349. however that $abs{a}leq size(fl(a))$ does not always hold). This
  1350. establishes (ref{M}). Inequality (ref{fl}) implies (ref{I}).
  1351. If $E = E_1op E_2$ then let
  1352. $tilde{E}$, $tilde{E}_1$, and $tilde{E}_2$ be the computed values for
  1353. $E$, $E_1$, and $E_2$. Then $abs{E_i}leq mes(E_i)$, $abs{tilde{E}_i}leq 
  1354. size(tilde{E}_i)leq mes(E_i)$, 
  1355. and $abs{tilde{E}_i - E_i}leq ind(E_i)cdot epscdot mes(E_i)$. Use 
  1356. $err(E_i)$ to abreviate $tilde{E}_i - E_i$.
  1357. Assume first that $E = E_1 + E_2$; the argument for subtraction is analogous.
  1358. Clearly, $size(E) = size(E_1 + E_2)leq 2cdot max(size(E_1),size(E_2))
  1359. leq 2cdot (mes(E_1),mes(E_2)) = mes(E)$ and
  1360. $size(tilde{E}) = size(tilde{E}_1oplus tilde{E}_2)leq
  1361. size(max(size(tilde{E}_1),size(tilde{E}_2))oplus 
  1362. max(size(tilde{E}_1),size(tilde{E}_2)))leq
  1363. size(2cdot max(mes(E_1),mes(E_2))) leq size(mes(E)) = mes(E)$
  1364. where the first inequality follows from the monotonicity of $oplus$ 
  1365. and the second inequality follows from the fact that equal powers of
  1366. two are added exactly. Similar reasoning shows that 
  1367. $size(tilde{E}_1+tilde{E}_2)leq mes(E)$. We turn to the error bound
  1368. next. We have
  1369. [
  1370. begin{array}{ll}
  1371. abs{tilde{E} - E}
  1372. &= abs{tilde{E}_1oplus tilde{E}_2 -(tilde{E}_1+tilde{E}_2)+tilde{E}_1 + 
  1373.        tilde{E}_2 - E_1 - E_2}\
  1374. & leq 1/2cdot epscdot size(tilde{E}_1+tilde{E}_2) + err(E_1) + err(E_2)\
  1375. & leq (1/2cdot mes(E) + ind(E_1)cdot mes(E_1) + ind(E_2)cdot 
  1376.        mes(E_2))cdot eps\
  1377. & = (1+ind(E_1) + ind(E_2))/2 cdot mes(E)cdot eps,
  1378. end{array}
  1379. ]
  1380. where the first inequality follows from (ref{op}).
  1381. Assume next that $E = E_1cdot E_2$. We leave it to the reader to show
  1382. that $size(E)leq mes(E)$, $size(tilde{E}) leq mes(E)$,
  1383. and $size(tilde{E}_1cdot tilde{E}_2)leq mes(E)$. For the error
  1384. bound we obtain
  1385. [
  1386. begin{array}{ll}
  1387. abs{tilde{E}-E}
  1388. &= abs{tilde{E}_1odot tilde{E}_2 - tilde{E}_1cdot tilde{E}_2 + 
  1389.    (E_1 + err(E_1))cdot (E_2 + err(E_2))- E_1cdot E_2}\
  1390. &leq 1/2cdot epscdot size(tilde{E}_1cdot tilde{E}_2)
  1391.    + err(E_1)cdot abs{E_2} + abs{tilde{E}_1}cdot err(E_2)\
  1392. &leq (1/2cdot mes(E) + ind(E_1)cdot mes(E_1)cdot size(E_2)
  1393.    + size(E_1)cdot ind(E_2)cdot mes(E_2)cdot eps \
  1394. &= (1/2 + ind(E_1) + ind(E_2))cdot epscdot mes(E)
  1395. end{array}
  1396. ]
  1397. This completes the proof of the lemma.
  1398. end{proof}
  1399. How are we going to use the error estimates? Assume that |E| is an expression
  1400. involving underline{integral} operands and operators $+,-$, and
  1401. $*$. Assume further that we want to know the sign of |E|. We evaluate
  1402. |E| using floating point arithmetic, i.e., we convert the operands into
  1403. floating point numbers and then use the floating point operations
  1404. $oplus$, $ominus$, and $odot$, and we also compute the quantities
  1405. $mes(E)$ and $ind(E)$ using rules (ref{first rule}) to (ref{sixth rule}).
  1406. Let $tilde{E}$ be the computed floating point approximation for |E|.
  1407. Note that $tilde{E}$ is an integer. We have:\
  1408. If $abs{tilde{E}} > ind(E)cdot mes(E)cdot eps$ then
  1409. $sign(tilde{E}) = sign(E)$, i.e., the sign of $tilde{E}$ is reliable. This
  1410. follows immediately from 
  1411. $abs{tilde{E} - E}leq ind(E)cdot mes(E)cdot eps$.\
  1412. If $abs{tilde{E}}leq ind(E)cdot mes(E)cdot eps < 1$ then 
  1413. $tilde{E} = E = 0$. This follows from
  1414. $abs{tilde{E} - E}leq ind(E)cdot mes(E)cdot eps$ and the fact 
  1415. that |E| and $tilde{E}$ are integers.\
  1416. If $abs{tilde{E}} leq ind(E)cdot mes(E)cdot eps$ and
  1417. $ind(E)cdot mes(E)cdot epsgeq 1$ then the signs of |E| and $tilde{E}$
  1418. may be different.
  1419. @ Implementation.
  1420. The filter is realized by a data type (class) |floatf| in C++. |floatf|,
  1421. can be used in the same way as the built-in numerical type |double|.
  1422. The only exception is that the result of some tests may be unreliable.
  1423. In particular there is a function |Sign(floatf x)| that tries to compute the 
  1424. sign of $x$. Possible results are |-1|, |O|, |+1| and |NO_IDEA|. The last 
  1425. value indicates that the sign of $x$ could not be computed.
  1426. Each instance of type |floatf| has three data members: |num|, $mes$, and $ind$.
  1427. |num| is the floating-point approximation of the integer $x$ to be represented, 
  1428. $mes = mes(x)$ and $ind = ind(x)$ are the bounds defined in the previous 
  1429. section. We define initialization and operations $+$, $-$, $*$ following the 
  1430. rules given in Lemma~1. A minor complication arises from tha fact that
  1431. rules (8) and (10) are evaluated using single precision 
  1432. floating point arithmetic. We compensate the error in these calculations
  1433. by multiplying with the correction factor $1 + 8cdot 2^{-23}$. 
  1434. The |Sign| operation is realized by a 
  1435. number of simple comparisons.
  1436. The details of the implementation are given below.
  1437. @(floatf.h@>=
  1438. #include <LEDA/basic.h>
  1439. #include <LEDA/integer.h>
  1440. #include <math.h>
  1441. const double eps0 = ldexp(1,-53);  // machine $epsilon = 2^{-53}$
  1442. const float correction = 1 + ldexp(1,-20);  
  1443. const int NO_IDEA = 2;
  1444. class floatf {
  1445.   double num;
  1446.   double mes;
  1447.   float  ind;
  1448.   floatf(double d, double m, float i) { num = d; mes = m; ind = i; }
  1449. public:
  1450. floatf() { num = 0; mes = 0; ind = 0; }
  1451. floatf(integer i)
  1452. { /* rules (ref{first rule}) and (ref{second rule}).
  1453.      Note that |ldexp(1,x)| is $2^x$ and that |Ilog(i)| is $lfloor logabs{i}
  1454.      rfloor$ for $i not= 0$ and $-1$ for $i =0$. Thus |Ilog(i-1) + 1|$ = 
  1455.      lceil log i rceil$ for $ i > 0$. 
  1456.    */
  1457.  
  1458.   if (i == 0) 
  1459.      { num = 0; mes = 0; ind = 0; }
  1460.   else
  1461.      { num = i.todouble(); 
  1462.        mes = (i > 0) ? ldexp(1,log(i)+1) : ldexp(1,log(-i)+1); 
  1463.        ind = (mes <= 53) ? 0 : 0.5;
  1464.       }
  1465. }
  1466. operator double() const { return num; } 
  1467. friend floatf operator+(const floatf& a, const floatf& b)
  1468. { //rules (ref{third rule}) and (ref{fourth rule}) 
  1469.   return floatf(a.num + b.num, 2*((a.mes > b.mes) ? a.mes : b.mes),
  1470.                              correction* (a.ind + b.ind + 1)/2);
  1471.  }
  1472. friend floatf operator-(const floatf& a, const floatf& b)
  1473. { //rules (ref{third rule}) and (ref{fourth rule})
  1474.   return floatf(a.num - b.num, 2*((a.mes > b.mes) ? a.mes : b.mes),
  1475.                             correction*  (a.ind + b.ind+ 1)/2);
  1476.  }
  1477. friend floatf operator*(const floatf& a, const floatf& b)
  1478. { //tules (ref{fifth rule}) and (ref{sixth rule})
  1479.   return floatf(a.num * b.num, a.mes * b.mes, 
  1480.                  correction* (a.ind + b.ind + 0.5));
  1481.  }
  1482. friend int Sign(const floatf& f)
  1483. { double eps = f.ind * f.mes * eps0;
  1484.   if (f.num >  eps) return +1;
  1485.   if (f.num < -eps) return -1;
  1486.   if (eps < 1) return 0;
  1487.   return NO_IDEA;
  1488.  }
  1489.  
  1490. };
  1491. @ label{float-restrictions}
  1492. Note that the quantities $mes$ and $ind$ are computed using double- and 
  1493. single-precision floating point arithmetic. The implementation is 
  1494. therefore correct as long as $mesleq 2^{1024}$ and $ind$ is a 
  1495. binary number with at most 24 bits.
  1496. %The procedure |sweep| takes a list of |rat_segment|s and computes the graph 
  1497. %induced by them. Recall that a |rat_segment| is specified by a pair of 
  1498. %|rat_point|s and that a |rat_point| is given by its homogeneous coordinates 
  1499. %$(X,Y,W)$ of type |integer|. The input must be such that there are integer 
  1500. %constants $k$ and $l$ with $5k + 3l <= 450$, $mid X mid, mid Ymid < 2^k$, 
  1501. %and $1 le mid Wmid le 2^l$ for all segment endpoints.
  1502. @* Experiments and Efficiency.
  1503. label{experiments}
  1504. We performed tests on three kinds of test data: 
  1505. difficult inputs, random inputs and  hand-crafted examples.
  1506. begin{itemize}
  1507. item
  1508. Difficult inputs:
  1509. Let $size$ be a random $k$-bit integer and
  1510. let $y = 2size/n$. We intersect $n$ segments where the $i$-th segment 
  1511. has endpoints $(size + rx1$, $2 cdot size  -i cdot y + ry1)$ and 
  1512. $(3size + rx2$, $2size + i cdot y + ry2)$ where $rx1$, $rx2$, $ry1$, $ry2$ 
  1513. are random integers in $[-s,s]$ for some small integer $s$. 
  1514. item 
  1515. Random inputs: 
  1516. We generated $n$ (between 1 and several hundred) segments
  1517. with random coordinates between $-size$ and $size$ for some parameter $size$. 
  1518. For $size$ we used large values to test the correctness and efficiency of the
  1519. floating point filter and the long integer arithmetic and small values to
  1520. test our claim that we can handle all degeneracies (a set of 100 segments whose
  1521. endpoints have integer coordinates between -3 and +3 is highly degenerate).
  1522. item Hand-crafted examples: We handcrafted some examples that exhibited a 
  1523. lot of degeneracies. We also asked students to break the code and offered 
  1524. DM 100.- for the first counter-example.
  1525. end{itemize}
  1526. Table ref{difficult} gives the result for the difficult inputs with 
  1527. $s=3$, $k=10,15,20,cdots,100$, and $n=100$. It lists the number 
  1528. of intersection and the running times
  1529. with and without the floating point filter. Furthermore it
  1530. gives  the percentage of the comparisons of points in the X-structure 
  1531. that were left undecided by the floating point filter (failure
  1532. rate) and  the percentage of tests where the floating point computation 
  1533. would have decided incorrectly (error rate).
  1534. begin{table}
  1535. begin{tabular}{rccccc}
  1536. $k$ & $|V|$ & without filter &  with filter & failures & errors  \
  1537. hline
  1538.  10 &  1323 &  0.78 &  0.37  &   0.05% &  0.00% \
  1539.  15 &  1323 &  0.68 &  0.40  &   0.04% &  0.00% \
  1540.  20 &  1314 &  0.70 &  0.38  &   0.12% &  0.05% \
  1541.  25 &  1325 &  0.77 &  0.42  &   0.08% &  0.05% \
  1542.  30 &  1318 &  0.75 &  0.45  &   1.48% &  0.73% \
  1543.  35 &  1321 &  1.03 &  0.52  &   0.94% &  0.39% \
  1544.  40 &  1312 &  1.27 &  0.55  &   2.17% &  1.02% \
  1545.  45 &  1325 &  1.27 &  0.77  &  20.98% &  2.19% \
  1546.  50 &  1323 &  1.45 &  1.23  &  73.33% & 19.98% \
  1547.  55 &  1325 &  1.90 &  1.68  &  86.35% & 44.74% \
  1548.  60 &  1325 &  1.33 &  1.52  &  83.52% & 58.07% \
  1549.  65 &  1321 &  2.20 &  1.90  &  89.66% & 65.21% \
  1550.  70 &  1323 &  2.07 &  1.87  &  86.88% & 63.41% \
  1551.  75 &  1316 &  2.57 &  2.30  &  89.93% & 67.89% \
  1552.  80 &  1323 &  2.62 &  2.08  &  89.90% & 67.33% \
  1553.  85 &  1321 &  2.63 &  2.98  &  83.11% & 62.74% \
  1554.  90 &  1313 &  2.78 &  2.48  &  90.96% & 67.88% \
  1555.  95 &  1319 &  3.03 &  3.07  &  81.74% & 62.33% \
  1556. 100 &  1323 &  3.12 &  3.13  &  89.19% & 67.05% \
  1557. end{tabular}
  1558. caption{The difficult example with 100 segments.}label{difficult}
  1559. end{table}
  1560. Comparing the $x$-coordinates of two intersection points is tantamount 
  1561. to testing the sign of a fifth degree homogeneous
  1562. polynomial in the coordinates of the segment endpoints. These coordinates
  1563. are of the form $size + rx$, $3size + rx$, $2size + icdot y + ry$, $2size -i
  1564. cdot y + ry$.
  1565. Thus, if we write the polynomial in terms of the perturbations $rx$ and
  1566. $ry$ we essentially obtain a term of order $size^5$ independent of the
  1567. perturbations (this term is actually zero but has maximal size in
  1568. intermediate results) plus a term or order $size^4$ times a linear
  1569. function in the perturbations plus a term of order $size^3$ times a
  1570. quadratic function in the perturbations $cdots$ . Since the input
  1571. coordinates are not equal to |size| but vary between $size$ and $3size$
  1572. the various terms are actually spread out over some orders of magnitude.
  1573. In the floating point filter analysis the error bound $delta$ is about
  1574. $3size^5 cdot 2^{-53}$. We conclude that the floating point filter
  1575. becomes worthless for $k$ about 50 and that we are starting to loose
  1576. the linear terms for $k$ about 40. For smaller $k$ the filter fails
  1577. only in those rare cases where the second order term must decide. This is
  1578. well reflected in Table ref{difficult}. 
  1579. begin{table}
  1580. begin{tabular}{rccccc}
  1581. $k$ & $|V|$ & without filter & with filter & failures & errors \ 
  1582. hline
  1583.   10& 1298  & 0.57  & 0.35   &  0.00%  &  0.00% \
  1584.   30& 1373  & 0.87  & 0.53   &  0.00%  &  0.00% \
  1585.   50& 1526  & 1.78  & 0.78   &  0.00%  &  0.00% \
  1586.   70& 1298  & 2.17  & 0.70   &  0.00%  &  0.00% \
  1587.   90& 1417  & 2.05  & 0.83   &  0.00%  &  0.00% \
  1588.  110& 1144  & 2.08  & 0.77   &  0.00%  &  0.00% \
  1589.  130& 1222  & 2.82  & 1.25   &  0.00%  &  0.00% \
  1590.  150& 1434  & 4.72  & 1.37   &  0.00%  &  0.00% \
  1591.  170& 1189  & 3.65  & 1.25   &  0.00%  &  0.00% \
  1592.  190& 1463  & 6.20  & 1.63   &  0.00%  &  0.00% \
  1593.  210& 1401  & 7.63  & 8.12   & 54.66%  & 34.06% \
  1594.  230& 1270  &10.58  & 8.48   & 51.53%  & 29.26% \
  1595.  250& 1608  &14.05  & 9.72   & 56.75%  & 33.74% \
  1596.  270& 1226  & 9.03  & 6.68   & 46.28%  & 29.02% \
  1597.  290& 1576  &14.55  &12.27   & 49.03%  & 28.17% \
  1598.  310& 1260  &15.12  &11.10   & 46.25%  & 28.21% \
  1599.  330& 1280  &12.93  &11.35   & 48.15%  & 29.52% \
  1600.  350& 1250  &13.25  &16.80   & 87.45%  & 42.02% \
  1601.  370& 1343  &24.97  &21.37   & 86.42%  & 46.91% \
  1602.  390& 1420  &20.55  &20.50   & 87.96%  & 46.30% \
  1603.  400& 1391  &22.38  &23.30   & 89.26%  & 47.10% \
  1604. end{tabular}
  1605. caption{100 random segments, coordinates are random $k$-bit integers.}
  1606. label{random}
  1607. end{table}
  1608. Table ref{random} gives the results for 100 segments whose endpoints have 
  1609. random $k$ bit coordinates. The experiments inidicate that the floating point filter reduces the
  1610. running time of the program by a factor of 2. 
  1611.  
  1612. More experiments with different floating
  1613. point filters are described in cite{IFIP94}.
  1614. @* Conclusion.
  1615. We have given an implementation of the Bentley-Ottmann
  1616. plane sweep algorithm for line segment intersection. The implementation is
  1617. complete and reliable in the sense that it will work for all input instances.
  1618. It is asympotically more efficient than previous algorithms for the same task;
  1619. its running time  depends on the number of vertices in the intersection
  1620. graph and not on the number of pairs of intersecting segments. It also
  1621. achieves a low constant factor in its running time by means of a floating
  1622. point filter.
  1623. The use of LEDA makes the implementation  of the combinatorial part of the
  1624. algorithm quite elegant. In the geometric part we have not achieved the same
  1625. level of elegance yet. We are currently exploring whether the
  1626. floating point filter can be completely hidden from the user as suggested in
  1627. cite{Yap-Dube:Exact-Computation}.
  1628. newpage
  1629. begin{thebibliography}{10}
  1630. bibitem{Bentley-Ottmann} 
  1631. J.L.~Bentley and T.A.~Ottmann. 
  1632. newblock Algorithms for reporting and counting geometric intersections.
  1633. newblock {em IEEE Trans. Comput.}, C-28:643--647, 1979.
  1634. bibitem{Burnikel-et-al}
  1635. C.~Burnikel, K.~Mehlhorn, and S.~Schirra.
  1636. newblock On degeneracy in geometric computations.
  1637. newblock In {em Proc. of the 5th ACM-SIAM Symp. on Discrete Algorithms},
  1638.   pp. 16--23, 1994.
  1639. bibitem{Cormen-Leiserson-Rivest}
  1640. T.H. Cormen and C.E. Leiserson and R.L. Rivest.
  1641. newblock Introduction to Algorithms.
  1642. newblock MIT Press/McGraw-Hill Book Company, 1990.
  1643. bibitem{Fortune-vanWyk}
  1644. S.~Fortune and C.~van Wyk.
  1645. newblock Efficient exact arithmetic for computational geometry.
  1646. newblock In {em Proc. of the 9th ACM Symp. on Computational Geometry},
  1647.   pp. 163--172, 1993.
  1648. bibitem{Mehlhorn-book}
  1649. K.~Mehlhorn.
  1650. newblock Data Structures and Efficient Algorithms.
  1651. newblock Springer Publishing Company, 1984.
  1652. bibitem{Myers}
  1653. E.~Myers.
  1654. newblock{An $O(E log E + I)$ expected time algorithm for the planar
  1655. segment intersection problem.}
  1656. newblock {em SIAM J. Comput.}, pp. 625 --636, 1985.
  1657. bibitem{LEDA-Paper}
  1658. K.~Mehlhorn and S.~N"aher.
  1659. newblock {LEDA}: A library of efficient data types and algorithms.
  1660. newblock In {em LNCS}, 379:88--106, 1989.
  1661. bibitem{IFIP94}
  1662. K.~Mehlhorn and S.~N"aher.
  1663. newblock The Implementation of Geometric Algorithms.
  1664. newblock 13th World Computer Congress IFIP 94, Elsevier Science B.V., 
  1665. Vol. 1, pp. 223--231, 1994.
  1666. bibitem{LEDA-Manual}
  1667. S.~N"aher.
  1668. newblock LEDA Manual.
  1669. newblock Technical Report No. MPI--I--93--109.
  1670. newblock Max-Planck-Institut f"ur Informatik, 1993.
  1671. bibitem{Preparata-Shamos}
  1672. F. Preparata and M.I. Shamos.
  1673. newblock Computational Geometry: An Introduction.
  1674. newblock Springer Publishing Company, 1985
  1675. bibitem{Yap-Dube:Exact-Computation}
  1676. Ch. Yap and Th. Dub'{e}.
  1677. newblock The exact computation paradigm.
  1678. newblock In {em Computing in Euclidian Geometry}, World Scientific
  1679. Press, 1994. (To appear, 2nd edition).
  1680. end{thebibliography}
  1681. end{document}