You are on page 1of 30

Lees O(n2 log n) Visibility Graph Algorithm

Implementation and Analysis


Dave Coleman

Department of Computer Science


(Dated: May 2, 2012)

I. ABSTRACT

Visibility graphs have many applications, including


finding the shortest path, robotic motion planning and
the art-gallery problem. The first non-trivial algorithm developed for finding the visibility graph runs in
O(n2 log n) and is presented in this paper. Its correctness, space, and time usage are mathematically analyzed.
Because faster algorithms to solve this problem have been
discovered, this paper is somewhat original in its analysis and implementation details of an otherwise forgotten
algorithm.

II.

INTRODUCTION

A. Visibility Graph

Visibility is an important property in computational


geometry and is used in many different types of problems, structures and algorithms [8]. One of the most
basic structures is the visibility graph, where an input
graph G describes a set of geometric primitives in an
d-dimensional space, and the output visibility graph
Gv describes the visibility between every vertex and
every other vertex in G. Here, we define visibility as
the ability to run a straight line between two vertices
without crossing any other edge in the input graph G. In
this way, two visible vertexes are said to be unobstructed
by any obstacle, and a line is drawn between them in
the output Gv . An example visibility graph in d = 2
dimensions Euclidean space is shown in Figure 1.
The set of geometric primitives inG can consist of a
variety of different types of shapes: rectilinear, circular,
line segments, convex polygons or, most generally,
simple polygons. Many different algorithms have been
developed based on the assumption of which types of
geometric primitives are allowable. In this paper we will
focus on simple non-intersecting line-segments, so as to
simplify our proofs and analysis. Very little modification
would be required to expand the problem space to
general polygons.
The layout of the geometric primitives is another vari-

david.t.coleman@colorado.edu;

www.davetcoleman.com

FIG. 1: Top: An input graph G consisting of a set of simple


line segments. Bottom: a generated visibility graph Gv describing all possible non-obstructed connections between each
vertex.

ation between computational geometry papers. In some,


visibility within a simple polygon is the only problem
space, but more often there exists obstacles within the
space, also referred to as holes or islands. Another variation of the visibility graph for all points is finding the
visibility tree for just one point, which is simply a subproblem of the visibility graph for all points.

2
B. Applications

Visibility graphs are most often thought of for use in


Euclidean shortest-path problems, were a start point s
and end point t are given and the task is to find the
optimal continuous path through the obstacle space
without violating physical constraints. This application
exploits the fact that the shortest paths are found on
the arcs of the visibility graph. Once the visibility graph
has been constructed, the shortest path problem can
be trivially solved using well known algorithms such
as Dijkstras [6], A* search[5], or Floyd-Warshall [3]
algorithms.
Robotic motion planning is a common sub problem
of the shortest path problem, as demonstrated in
Lozano-Perez and Wesleys 1979 collision-free paths
algorithm [11]. One of the most famous examples
of visibility graphs used in robotic motion planning
is Shakey the Robot [11]. However, the application
of visibility graphs realistically limits the workspace
to two dimensions and is generally computationally
intractable for modern real-world robotics problems.
Sampling-based approaches are considered the current
state of the art and, although unable to determine
that no path exists, have a probability of failure that
decreases to zero as more computational time is spent [7].
Additional applications of visibility graphs include
finding the minimum dominating set to help solve the art
gallery problem and in solving pursuer-evader problems
[10]. Finally, visibility graphs can be used to optimize radio antenna placement, urban planning and architectural
design [1].

C. History

average, or handle sparse graphs more efficiently. One of


the last papers published on visibility graphs during this
time period achieved O(|e| + n log n) time bounds, which
are output-sensitive algorithms optimal for graphs of a
certain minimum density threshold [4].

III.
A.

METHODS

Description of the Algorithm

Lees O(n2 log n) algorithm computes the visibility


graph Gv from G(V, E) by computing the visibility
graph of a single vertex n times. For each vertex vi V ,
the visibility of all other vertices is calculated by 1)
sorting all surrounding vertices in angular order from
some starting scan line, 2) using a rotating plane sweep
technique to visit each vertex in angular order and 3)
keeping track of the distance of each surrounding line
segment on the scan line in a sorted data structure. The
following details these 3 procedures:
For each vi V a visibility tree is generated describing
the visibility of all other points vj V vi with respect
to vi . Each visibility tree is created by setting vi to
be the center vertex c. A starting scan line vector s is
initialized for each c, with the origin of the vector at c.
Its direction is irrelevant for the algorithm but in this
paper and implementation s will be assumed to be the
horizontal unit vector i pointing straight and to the
right from c, i.e. s = i = [1, 0].
From scan line s = i we calculate the counter clockwise
angle i = angle(scvi , i) for every vertex vi V c.
The angles are inserted to an optimally sorted data
structure A from smallest to largest.

The naive approach to computing the visibility of a


graph runs in O(n3 ) times. The first non-trivial solution
to this problem was developed by D.T. Lee in his 1978
Ph.D. dissertation that ran in O(n2 log n) time [9]. The
solution is included at the end of his thesis as somewhat
of a side thought and it has since then received very
little attention in the computational geometry field.
Only available upon email request, the typed report
includes hand-written edits and drawings. This is the
algorithm that will be analyzed in this paper.
In the 1980s a large number of O(n2 ) visibility graph
papers were published, most of which entailed a topological sort of the vertex pairs. E. Welzl in particular
described this technique using an arrangement of the
dual of the vertices that required O(n2 ) working space
[13]. The working storage of the topological sweep was
later improved to O(n) by Edelsbrunner and Guibas
[2]. Further improvements included handling dynamic
updates of the workspace, using less running time on

FIG. 2: Example of an initialized edge list with all edges that


intersect scan line s. Image courtesy of [8]

A second optimally sorted data structure Es is


initialized containing all the line segments li E that
intersect scan line s at the start of the algorithm. This
operation requires |E| checks, calculating if s and line
segment li intersect. The line segments that are found

3
to intersect are inserted into Es with their keys being
the distance from c to the intersection point v[i,i1]
such that the root of the sorted data structure always
contains the edge closest to c. We can intuitively see
that this root edge is the only edge visible from c at this
scan line instance. Figure 2 depicts an initialized scan
list, though in this example vector s is not horizontal.
After the initialization phase the algorithm visits
every vertex vi in order of i in A. The scan line does
not have to actually visit every angle in the circle, but
only those i where a vertex vi intersects s. For each
vi scanned, the algorithm decides if its corresponding
line segment lvi ,vi +1 is the first or last vertex seen of
its corresponding li . If it is the first vertex seen, then
lvi ,vi +1 is added to Es and is considered open. If it is
the second vertex seen, or if it was initialized as open on
s0 , then it is removed from Es and is considered closed.
For each visited vi , a check is made to see if vi is
the root of Es , signifying that vi is the closest vertex
to c with respect to s. If vi has this property, then
vi is considered visible and is added to the visibility
graph Gv ; otherwise it is obscured by some other edge
appearing before it, with respect to c, and is ignored.
In this way every visible vertex with respect to c is
found and a visibility tree is generated for some vi . This
process is repeated n times to build a complete visibility
graph.

B. Runtime

The asymptotic runtime of Lees algorithm is analyzed


in the following. The algorithm has four for-loops as well
as the operations of the optimal sorting data structure.
An outer for-loop iterates once through n = |V | = 2|E|
points, finding the visibility tree for every point.
Within the outer for loop, each end point pair for
every |E| line segments are inserted into the optimal
sorting data structure A. Insert, delete, and find all
take O(log n) time using a probabilistic structure such
as a skip list, or balance binary search tree, such as
an AVL tree. Thus, the insertion time for A takes
2|E| log n = O(n log n).
Next, the sweep line edge list Es is initialized by
checking all |E| edges in G for intersection with s = i.
The edge list Es uses the same data structure as A, and
thus all insertions take O(log n) time. In the worse case,
all |E| edges intersect s at some i , so the total runtime
for this step is O(|E| log |E|). There are twice as many
vertices as edges, and so because |E| < |V |, this runtime
is asymptotically overshadowed by the previous step and
can be ignored.

Finally, the sweeping for-loop begins its check of every


vi V c points. At each vertex a line is either inserted
into or removed from Es once, requiring again O(log n)
time for each operation. Thus the total running time for
this step is also (n 1) log n = O(n log n).
With these three steps and the outer forloop combined, our summed running time is
O(n (.5n + n + n 1) log n), which asymptotically reduces to simply O(n2 log n).

C. Space Requirements

The space requirements of Lees algorithm is analyzed


in the following. The input graph G requires O(V + E)
space, but we will assume that the input graph is not
included in our space requirements.
Two optimum sorting data structures are needed in
the algorithm - A and Es . D.T. Lees original paper suggested an AVL tree be used; in our implementation we
have used a skip list. Regardless, both use O(n) space,
totaling 2O(n). Because each i is inserted into A once,
n = |V | for datastructure A. In the worse case all edges
are intersected by s at the same time, making Es have
size n = |E| = .5|V |. No other memory is used in the
algorithm, so the total overall space requirements, not including the input graph, is O(1.5|V |), which is equivalent
to simply O(n).

D. Analysis of Correctness

We begin our proof of correctness of Lees O(n2 log n)


algorithm by defining the components of the algorithm.
Definition 1. A visibility graph Gv = (V, Ev ) is the set
of all vertices V in input graph G, and the set of edges
Ev which connects two vertices vi , vj V without intersecting any obstacles, for all vi , vj V . We assume that
two endpoints i and j of the same line are also considered
visible. We restrict our obstacle set to the |E| disjoint
line segments, in any direction.
Definition 2. The line sweep vector s is a vector with
its origin at some point c V that rotates starting from
direction i a full 2 radians.
Definition 3. A line segment li is an obstacle in the
2 dimensional problem space defined between vertices vi
and vi1 .
Definition 4. The set Es contains all li that intersect
with s originating at point c, ordered in decreasing Euclidean distance from c to li .

4
The above definitions we will now begin to prove the
algorithms correctness by observing the existence of
optimal substructure of the visibility graph:
Lemma 1. The visibility tree containing set of all edges
Ei connecting a single point vi to all other visible points
vj V vi , with respect to the single point vi , is a subsolution to finding the visibility graph of all points vj V
in G.
Proof. Assume the visibility tree Ei for some vi is generated correctly every time. For N = 1 points, by the just
stated assumption no other endpoint vj of a line segment
is visible from that N = 1 point that is not already in the
set Ei=1 . For N = 2 points, following the same assumption, no point will be visible to those N = 2 points that
is not already in the combined visibility tree set Ei=[1,2] .
For N = |V | points, it follows that no point in V will be
visible from any other point in V that is not already in
the set Ei=1N . In this case our above definition of a
visibility graph is satisfied and our N sub-solutions have
resulted in correctly finding the visibility graph Gv for
all points vj V .
Lemma 1 assumed that the set of edges Ei defining a
visibility tree, for some vertex i, was generated correctly
every time.
We now prove our algorithm for this
subproblem. We begin by defining the assumptions of
our scan line method:
Lemma 2. No more than one obstacle is visible at any
time from a center point c with respect to the direction of
a scan line vector s at any angle in Euclidean space.
Proof. A Euclidean vector is defined as a geometric object that has a direction and length (or magnitude), but
it does not itself have a width, or at least the width could
be considered infinitely narrow. An infinitely narrow segment of a directional vector could not be obstructed by
more than n = 1 geometric element at a time because
otherwise the combined width of n > 1 geometric elements would have to be infinitely small. The combined
width of two objects would be greater than infinitely
small. Therefore, because obstacles in our problem space
are assumed to be line segments, our lemma stands.
Corollary 1. The intersection point of s and li Es
with the minimum Euclidean distance to c is the only
line segment visible.
Proof. Although s may cross several li Es , by Lemma
2 we know only one point can have the visible property
for a given s, and by the definition of visibility we know
it must be the first line segment it reaches. The first line
segment a vector crosses from some point c is the segment
closest in Euclidean distance.

With Lemma 2 and Corollary 1 we have proved


the correctness of the results of scan line s at one i .
We will now expand our proof to all 2 and our
discretization method.
Lemma 3. No change is made in the visibility of any
line segment with respect to s except when s intersects
an end point of some line segments.
Proof. By contradiction. Assume the set Es correctly
contains all line segments that intersect some vector s
and assume s is at some a that does not intersect any
end points vi V . The only way to change the visibility
of a line segment at s would be to remove the first line
segment Es because this is the line segment closest to
c. Suppose we removed this line segment, despite having
no vi in intersection with s. Then there exists a li that
intersects s and Es violates definition 4 defining what Es
must contain, and by contradiction this lemma is proved.

Corollary 2. In the non-discrete angular space between 0 and 2, our scan line need only check |V | 1
discrete steps where i = angle(scvi , i),.
Proof. Following from Lemma 3, no changes in visibility
occur with respect to the rotation of s around c except
when s intersects an end point vi , and there are only
|V | 1 endpoints around c so it follows that only |V | 1
angles of i need to be checked.
The utility of a scan line is now sufficiently proven by
Lemma 3 and Corollary 2. The mechanism for tracking
the removal and insertion of lines into Es is now proved:
Lemma 4. A line segment li with an end point vi in
intersection with s must be added to the set Es if the opposite end point vi1 of li has not previously been visited
(the line was closed). Otherwise, if it has been previously visited, li must be removed from the set Es (the line
was open).
Proof. Following the stated assumption that s rotates in
a counter clockwise direction, and recalling that at initialization all li in intersection with s are added to Es
and marked as open, it can be observed that Lemma 4 is
required to maintain Definition 4, that Es must contain
all line segments that intersect s.
Using Lemmas 1 to 4 and Corollaries 1 and 2 the
following theorem is supported:
Theorem 1. Given a set of n disjoint line segments
in the Euclidean plane, the visibility graph can be constructed correctly in O(n2 log n) time using the rotational
sweep method in Lees algorithm.

5
IV. RESULTS
A. Implementation

The O(n2 log n) algorithm was implemented in


C++ and visualized/animated using the open source,
cross-platform CImg graphics library. With the graphics library we were able to visually verify geometric
results such as shown in Figure 3. The full source
code is appended at the end of this paper and is
available as an open source project online at https:
//github.com/davetcoleman/visibility_graph

line s would visit and so it would be inserted into the


skip list Es with the distance d1 from its first endpoint
to c. Next, the scan line would visit the first endpoint
of l2 and it would add l2 to Es with distance d2 . Thus,
Es would have as its first ordered line segment l1 , and
for its seconds l2 . But by definition 4, Es should have
as its first line segment the segment closest to c, and at
scan line sr the closest intersecting line segment is now
actually l2 . As it is now clear, in our current example
the ordering of Es would be incorrect at location sr
unless there was some way to update the value of l1 to
reflect its distance from c with respect to i of sr .

FIG. 3: Test input graph of 8 line segments (white) and the


generated visibility graph of Ev lines (blue)
FIG. 4: Line l1 originally was the closest point to c, but at
scan line sr line l2 covers l1 . This demonstrates the need for
elements variable values in the skip list.
B. Skip Lists

D.T. Lees original paper suggested an AVL tree


data tree structure be used, but his paper was published before the invention of skip lists in 1989 by
W. Pugh [12]. In this implementation we chose to
use a skip list due to its average case performance
and advantage in concurrent access and modifications.
However, a unique property of our algorithm required
special modification to the skip list such that the key
values of data already in the skip list are variable.
That is to say, the value of each element in the skip
list changes as the scan line rotates around some center
c.
The need for this property is motivated in Figure 4.
In this example line l1 is the first line segment that scan

This might seem like an impossible property of a skip


list, but in fact there is an additional property that
states that the ordering of the items in the skip list
are guaranteed not to change, just the values. In other
words, although l1 at angle i has an intersection with
sr that is a greater distance than that of l2 from c, the
ordering of l1 in Es with respect to all other open line
segments in Es would remain unchanged due to the
assumption that no line segments can intersect in our
problem space.
Therefore, in implementing the actual visibility graph,
each line segment was represented as an object that
could quickly re-calculate its intersection with s and
then distance to c. This was accomplished by caching
the slope m and y-intercept b at the initialization of the

6
line object, as well as caching the resultant distance d
from c for every i such that d is only calculated once
for every thetai .

C. Precision Errors

Another issue with our implementation was rounding


errors that occurred when calculating the angles between
two close points. This was especially problematic as
we increased the number of line segments added to our
finitely-sized graphics window. Sometimes two unique
points would be added to the angle list A with the same
angle because of rounding errors, and the result was
that some points were mistakenly added as visible.
Particularly problematic were perfectly horizontal and
vertical lines. With vertical lines the slope m would tend
to infinity, but in this implementation it was faked with
some very large number. In the same way, a horizontal
line has a slope with an infinitely small m, and this again
suffered from the limitations of our computer hardware.

D.

FIG. 5: An example generated problem space for nx =


(|(10n )1/2 J)2 line segments, with randomly chosen shapes.

Numerical Time Usage

To calculate the numerical time usage of this algorithm, the source code was modified to automatically
generate a set of n line segments. To test the runtime
with exponentially increasing problem space it was
instrumented to generate approximately n = 10x line
segments. However, to ensure a useful test set was
generated without intersection, each line segment was
constrained to a grid area. Within each line segments
grid, padding was added to allow more visibility between
grids. Additionally, 4 shapes were used inside the grids:
a horizontal, vertical, diagonal increasing and diagonal
decreasing line segment. Which of the 4 was chosen was
decided at random, such that every test was run on a
problem set with a high probability of being unique.
Because of the gridded nature of the problem space,
in reality only nx = (|(10n )1/2 J)2 line segments were
added. An example of an automatically generated
problem space is shown in Figure 5.
With this setup, the numerical time usage was
measured by counting the number of atomic operations
within both the algorithm and the skip lists. The
algorithm was tested for n = 101 103.5 . At problem
size n = 104 the algorithm crashed on both our laptop
and on a node on the Janus super computer. This,
however, is mostly due to some memory leaks that were
problematic to patch.
The results of the atomic operations measurements are
shown in Figure 6. Our data showed performance that
was very tightly bound to a run time of O(n2 log n). This

run time is both the worst- and average-case for this algorithm because all points are always added to A and E
and all points are always visited to generate their individual visibility tree.

FIG. 6: Atomic operations of Lees visibility graph algorithm


for increasing number of line segments n.

Further visual results of the algorithm running for


n = 100 line segments is shown in Figure 7 and for
n = 1000 line segments in Figure 8.

7
considered to use 3 atomic memory amounts. A memory
counter was incremented for every new node created,
and decremented for every node deleted. A secondary
counter was used to track the maximum amount of
memory used at any point in the algorithms progress.
The results are shown in Figure 9. As expected, the
memory usage was on the order of O(n).

FIG. 7: Generated visibility graph for n = 100 line segments.

FIG. 9: Measured space usage of Lees visibility graph algorithm. The upper and lower dotted line bounds are multiplied
by constants of 3 and 7, respectively.

V.

FIG. 8: Generated visibility graph for n = 1000 line segments.

E. Numerical Space Usage

The numerical space usage of this algorithm was


measured by tracking the maximum number of nodes
from both skip lists combined at any point in the
algorithm. Here, we define a node as a level in the
skip list structure, such that a root with 3 levels is

CONCLUSIONS

There exists many additional optimization tweaks


that could be applied to this algorithm.
One such
optimization is to limit the scan line rotation to only
half the circle, from the observation that visibility
between a pair is mutual. Other optimizations could be
made in the geometric calculations such as studying the
performance advantages between finding the distance
using the line-of-sine method versus the intersection
method and dealing with slopes of negative and positive
infinity. Lastly, the dynamic-valued skip list structure
discussed in section IV. B. requires a large number of
distance calculations at every rotation of the scan line,
and could be reduced by only checking a vertices change
in distance immediately around the skip lists chosen
insertion point for a new line segment. While simple
in explanation, it would be complicated in required
modification to the skip list algorithm.
In this paper we have explained, analyzed, proved and
implemented D.T. Lees 1978 visibility graph algorithm.
As explained in the introduction, faster algorithms
have been developed that run on O(n2 ) time and other

8
optimizations have been discovered for special case
problems where certain geometric tricks can be utilized.
However, basic applications such as the shortest path
planning problem with no more than order O(n3 ) line
segments has been shown in this paper section to be
feasible with this algorithm and in our experiments have
generated visibility graphs in seconds.

[1] Burcin Cem Arabacioglu. Using fuzzy inference system


for architectural space analysis. Appl. Soft Comput.,
10(3):926937, June 2010.
[2] Herbert Edelsbrunner and Leonidas J. Guibas. Topologically sweeping an arrangement. Journal of Computer
and System Sciences, 38(1):165 194, 1989.
[3] Robert W. Floyd. Algorithm 97: Shortest path. Commun. ACM, 5(6):345, June 1962.
[4] Subir Kumar Ghosh and David M. Mount. An output
sensitive algorithm for computing visibility graphs. In
Proceedings of the 28th Annual Symposium on Foundations of Computer Science, SFCS 87, pages 1119, Washington, DC, USA, 1987. IEEE Computer Society.
[5] P.E. Hart, N.J. Nilsson, and B. Raphael. A formal basis
for the heuristic determination of minimum cost paths.
Systems Science and Cybernetics, IEEE Transactions on,
4(2):100 107, july 1968.
[6] Donald B. Johnson. A note on dijkstras shortest path
algorithm. J. ACM, 20(3):385388, July 1973.
[7] Sertac Karaman and Emilio Frazzoli. Sampling-based algorithms for optimal motion planning. Int. J. Rob. Res.,
30(7):846894, June 2011.

Acknowledgments

This paper was written for Aaron Clausets Graduate


Algorithms class at the University of Colorado Boulder.

[8] John Kitzinger and Computer Engineering. The visibility graph among polygonal obstacles: a comparison of
algorithms, 2003.
[9] Der-Tsai Lee. Proximity and reachability in the plane.
PhD thesis, Champaign, IL, USA, 1978. AAI7913526.
[10] Jae-Ha Lee, Sung Yong Shin, and Kyung-Yong Chwa.
Visibility-based pursuit-evasion in a polygonal room with
a door. In Proceedings of the fifteenth annual symposium
on Computational geometry, SCG 99, pages 281290,
New York, NY, USA, 1999. ACM.
[11] Tomas Lozano-Perez and Michael A. Wesley. An algorithm for planning collision-free paths among polyhedral obstacles. Commun. ACM, 22(10):560570, October
1979.
[12] William Pugh. Skip lists: a probabilistic alternative to
balanced trees. Commun. ACM, 33(6):668676, June
1990.
[13] Emo Welzl. Constructing the visibility graph for n-line
segments in o(n2) time. Information Processing Letters,
20(4):167 171, 1985.

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

C++ Code For Visibility Graph Implementation


Index:
vgraph.cpp
skiplist.h
line.h
line.cpp
point.h
point.cpp
geometry.h
plot.m
data.cvs

vgraph.cpp
#i n c l u d e
#i n c l u d e
#i n c l u d e
#i n c l u d e
#i n c l u d e
#i n c l u d e

CImg . h / / I n c l u d e CImg l i b r a r y h e a d e r .
<i o s t r e a m >
l i n e . h
p o i n t . h
s k i p l i s t . h
<cmath>

u s i n g namespace c i m g l i b r a r y ;
u s i n g namespace s t d ;
const
const
const
const
const
const
const

u n s i g n e d c h a r WHITE [ ] = { 2 5 5 , 2 5 5 , 255 } ;
u n s i g n e d c h a r GREY [ ] = { 1 0 0 , 1 0 0 , 100 } ;
u n s i g n e d c h a r BLACK [ ] = { 0 , 0 , 0 } ;
u n s i g n e d c h a r RED [ ] = { 2 5 5 , 0 , 0 } ;
u n s i g n e d c h a r GREEN [ ] = { 0 , 2 5 5 , 0 } ;
u n s i g n e d c h a r BLUE [ ] = { 0 , 0 , 2 5 5 } ;
int sc r een s iz e = 800;

//
// P r ototy pes
//
v o i d v graph ( d o u b l e o r d e r ) ;
d o u b l e v e c t o r s A n g l e ( i n t x , i n t y , i n t b as e x , i n t b a s e y ) ;
d o uble d i s t a n c e ( P oint a , Point b ) ;
//
/ / Main p r o c e d u r e
//
i n t main ( )
{
c o u t << e n d l << e n d l << V i s i b i l i t y Graph by Dave Coleman
<< e n d l ;
f o r ( d o u b l e o r d e r = 2 ; o r d e r < 3 ; o r d e r += 0 . 5 )
{
v graph ( o r d e r ) ;
}
r e t u r n EXIT SUCCESS ;
}
v o i d v graph ( d o u b l e o r d e r )
{
/ / V a r i a b l e s
/ / Atomic o p e r a t i o n c o u n t e r
atomic = 0 ;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<< e n 3
d1l
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

Page 1 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

/ / Gr aphics :
bool v i s u al = tr ue ;
bool l i v e = tr ue ;
CImg<u n s i g n e d c h a r > img ( s c r e e n s i z e , s c r e e n s i z e , 1 , 3 , 2 0 ) ;
CImgDisplay d i s p ( img , V i s i b i l i t y Graph ) ;
/ / D i s p l a y t h e m o d i f i e d image on t h e
scr een
/ / L ine segments :
i n t s i z e = pow ( 1 0 . 0 , o r d e r ) ;
int r ow col = sqr t ( s iz e ) ;
i n t seg = r ow col r ow col ;
// Coor dinates :
d o u b l e w i d t h = s c r e e n s i z e / r o w c o l ; / / s i z e o f e a c h g r i d box
d o u b l e margin = 0 . 1 w i d t h ;
/ / p a d d i n g i n s i d e e a c h box
d o u b l e top , bottom , l e f t , r i g h t ; / / c o o r d i n a t e s o f box w i t h p a d d i n g
/ / G e n e r a t e s p a c e f o r SEG number o f l i n e s
L ine s eg s [ seg ] ;
/ / Track what i n d e x we a r e on
i n t index = 0 ;
/ / Now g e n e r a t e s e g l i n e s e g m e n t s
f o r ( i n t x = 0 ; x < r o w c o l ; ++x )
{
f o r ( i n t y = 0 ; y < r o w c o l ; ++y )
{
t o p = y w i d t h + margin ;
bottom = ( y+1) w i d t h margin ;
l e f t = x w i d t h + margin ;
r i g h t = ( x+1) w i d t h margin ;
/ / C r e a t e l i n e segment i n box o f s i z e w i d t h w i d t h
/ / x1 , y1 , x2 , y2
s w i t c h ( rand ( ) % 4 )
{
c ase 0: // v e r t i c l e l i n e
s e g s [ i n d e x ] = new L i n e ( l e f t , top , l e f t , bottom ) ;
br eak ;
c ase 1: // h o r i z o n t a l l i n e
s e g s [ i n d e x ] = new L i n e ( l e f t , top , r i g h t , t o p ) ;
br eak ;
c ase 2: // diagonal l e f t to r i g h t
s e g s [ i n d e x ] = new L i n e ( l e f t , top , r i g h t , bottom ) ;
br eak ;
case 3:
s e g s [ i n d e x ] = new L i n e ( l e f t , bottom , r i g h t , t o p ) ;
br eak ;
}
i n d e x ++;
}
}
/ / c o u t << SEGS << s e g << INDEX << i n d e x << e n d l ;
/
L ine s e gs [ ] =
{
L ine ( 280 ,300 ,330 ,120) ,
L ine ( 450 ,150 ,280 ,330) ,
L ine ( 400 ,150 ,401 ,190) ,
L ine ( 400 ,400 ,450 ,200) ,
L ine ( 350 ,350 ,350 ,450) ,
L ine ( 10 ,200 ,100 ,215) ,

//
//
//
//
//
//

0
1
2
3
4
5

first
second
thir d , l a t e r
f ar r ight

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

Page 2 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

L ine ( 50 ,50 ,50 ,100) ,


L ine ( 200 ,450 ,300 ,450)
};

/ / R eusable p o i n t e r
L ine l ; P
oint p ;

// 6
// 7

locations

int center id ;
b ool isPointA ;
/ / V i s i t e a c h v e r t e x o n c e and p e r f o r m t h e v i s i b i l i t y
f o r ( i n t o u t e r = 0 ; o u t e r < 2 s e g ; ++o u t e r )
{
++a t o m i c ;

algor ithm

/ / F i r s t o r s e c o n d number on e a c h l i n e ?
c en t er i d = outer / 2;
/ / Garbage C o l l e c t
i f ( outer )
{
d elete center ;
delete c en ter line ;
}
/ / c o u t << LINE ID : << c e n t e r i d << e n d l ;
i f ( ! ( o u t e r % 2) ) // i s even
{
c e n t e r = new P o i n t ( s e g s [ c e n t e r i d ]>a>x , s e g s [ c e n t e r i d ]>a>y ) ;
isPointA = t r u e ;
}
e l s e // i s even
{
c e n t e r = new P o i n t ( s e g s [ c e n t e r i d ]>b>x , s e g s [ c e n t e r i d ]>b>y ) ;
isPointA = f a l s e ;
}
/ / C enter L ine C alc :
c e n t e r l i n e = new L i n e ( c e n t e r >x , c e n t e r >y , c e n t e r >x +1 , c e n t e r >y ) ;
/ / Add p o i n t e r s t o a l l p o i n t s back t o p a r e n t l i n e
c e n t e r >p a r e n t L i n e = s e g s [ c e n t e r i d ] ;
/ / Draw s w e e p e r :
// img . d r a w l i n e ( c e n t e r >x , c e n t e r >y , c e n t e r >x +200 , c e n t e r >y , RED) ;
i f ( visual )
img . d r a w c i r c l e ( c e n t e r >x , c e n t e r >y , 6 , RED) ;
/ c o u t << LINE ID << c e n t e r i d << ;
i f ( isPointA )
c o u t << A << e n d l ;
else
c o u t << B << e n d l ;
/
// D atastr uctur es :
s k i p l i s t <P o i n t> a n g l e L i s t ;
s k i p l i s t <L i n e> e d g e L i s t ;
/ / A l g o r i t h m
/ / Draw s e g m e n t s and i n s e r t POINTS i n t o s k i p l i s t o r d e r e d by ANGLE
f o r ( i n t i = 0 ; i < s e g ; ++i )
{
++a t o m i c ;
l = segs [ i ] ;

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

Page 3 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

182
183
184
185
186
// Reset v i s i t e d f l a g s
187
188
l >v i s i t e d = f a l s e ;
189
l >v i s i t e d S t a r t P o i n t = f a l s e ;
190
i f ( visual )
191
192
img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , WHITE) ;
193
194
i f ( ! ( i == c e n t e r i d && i s P o i n t A ) ) / / p o i n t i s n o t l i n e A
195
{
196
i f ( visual )
197
img . d r a w c i r c l e ( l >a>x , l >a>y , 2 , WHITE) ;
198
199
/ / C a l c u l a t e t h e a n g l e from c e n t e r l i n e :
200
l >a>t h e t a = v e c t o r s A n g l e ( l >a>x , l >a>y , c e n t e r >x , c e n t e r >y ) ;
201
202
// Sor t the v e r t i c i e s :
203
a n g l e L i s t . add ( l >a ) ;
204
205
/ / c o u t << Added A f o r l i n e << i << t h e t a << l >a>t h e t a << e n d l ;
206
/ / c o u t << POINT ; l >a>p r i n t ( ) ; c o u t << e n d l ;
207
}
208
209
i f ( ! ( i == c e n t e r i d && i s P o i n t A == f a l s e ) ) / / p o i n t i s n o t l i n e B
210
{
211
i f ( visual )
212
img . d r a w c i r c l e ( l >b>x , l >b>y , 2 , WHITE) ;
213
214
/ / C a l c u l a t e t h e a n g l e from c e n t e r l i n e :
215
l >b>t h e t a = v e c t o r s A n g l e ( l >b>x , l >b>y , c e n t e r >x , c e n t e r >y ) ;
216
217
// Sor t the v e r t i c i e s :
218
a n g l e L i s t . add ( l >b ) ;
219
/ / c o u t << Added B f o r l i n e << i << t h e t a << l >b>t h e t a << e n d l ;
220
/ / c o u t << POINT ; l >b>p r i n t ( ) ; c o u t << e n d l ;
221
222
}
223
224
/ / c o u t << e n d l ;
225
}
226
227
228
/ / T est S k i p L i s t
229
/ / c o u t << A ngle L i s t p o i n t s o r d e r e d CC from b a s e l i n e ;
230
// an gleL is t . p r i ntA ll ( ) ;
231
232
/ / I n i t i a l i z e Edge L i s t Of L i n e s
2
3
3
f o r ( i n t i = 0 ; i < s e g ; ++i )
234
235
{
236
++a t o m i c ;
237
l = s e g s [ i ] ; / / g e t next l i n e to check
238
239
/ / check i f the c u r r e n t l i n e i s c o n n ect e d t o th e c e n t e r p o i n t
240
241
i f ( l >i d == ( ( L i n e ) c e n t e r >p a r e n t L i n e )>i d )
242
{
243
/ / one c e n t e r s l i n e
/ / c o u t << ONE CENTER S LINE ! ! ! << e n d l ;
244
245
}
246
else
247
{
248
/ / Check e a c h l i n e and s e e i f i t c r o s s e s s c a n l i n e
double xi , y i ;
249
/ / Add p o i n t e r s t o a l l p o i n t s back t o p a r e n t l i n e
l >a>p a r e n t L i n e = l ;
l >b>p a r e n t L i n e = l ;

Page 4 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

l >c e n t e r i n t e r c e p t ( x i , y i ) ; / / t h e s e a r e r e f e r e n c e p a r a m e t e r s

250
251
/ / Now we know t h a t x i , y i i s on c e n t e r l i n e .
252
/ / Next we c h e c k i f X i s betw een a & b . We know a . x > b . x , t h u s :
253
254
i f ( l >a>x >= x i && l >b>x <= x i )
255
{
256
/ / c h e c k t h a t x i > c e n t e r >x
257
i f ( x i >= c e n t e r >x )
258
{
259
// I t does i n t e r s e c t
260
e d g e L i s t . add ( l ) ;
261
262
/ / Mark a s opened , somewhere on l i n e
263
264
l >v i s i t e d = t r u e ;
265
// V is u aliz e :
266
i f ( visual )
267
268
img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , GREEN) ;
269
}
270
}
271
}
272
}
273
274
if ( live)
275
d i s p . d i s p l a y ( img ) ;
276
277
/ / c o u t << Edge L i s t : ;
278
// edgeL ist . p r i n tA ll ( ) ;
279
/ / Sweep
280
281
282
// s leep ( 1) ;
283
// u s l e ep ( 5001000) ;
284
f o r ( i n t i = 0 ; i < 2 s e g 1 ; ++i )
285
{
286
++a t o m i c ;
287
/ / c o u t << \ n\n\n STARTING NEW SWEEP \n\n\n ; 288
289
/ / c o u t << SWEEP VERTEX << i << e n d l ;
290
// i f ( i > 0 )
291
/ / br eak ;
292
293
// tak e the f i r s t v er t ex i n angular or der
294
p = a n g l e L i s t . pop ( ) ;
295
296
/ / c o u t << Sweep a t ; p>p r i n t ( ) ;
297
/ / Update t h e c e n t e r l i n e t o t h e sweep l o c a t i o n and u p d a t e m, b
298
299
c e n t e r l i n e >b = p ;
300
c e n t e r l i n e >u p d a t e C a l c s ( ) ;
301
/ / Update c e n t e r p o i n t t o c o n t a i n t h e t a betw een b a s e l i n e and
302
/ / c u r r e n t p o i n t , s o t h a t o u r l i n e f u n c t i o n can c a c h e
303
304
c e n t e r >t h e t a = p>t h e t a ;
305
/ / d e c i d e what t o do w i t h i t
306
307
l = ( L i n e ) p>p a r e n t L i n e ; / / c a s t i t
308
/ / c o u t << \ t ; l >p r i n t ( ) ;
309
310
/ / check i f the c u r r e n t l i n e i s c o n n ect e d t o th e c e n t e r p o i n t
311
i f ( l >i d == ( ( L i n e ) c e n t e r >p a r e n t L i n e )>i d )
312
{
313
/ / one c e n t e r s l i n e
314
// ignor e
315
}
316
e l s e i f ( l >v i s i t e d
) / / remove i t from e d g e L i s t
317
{

Page 5 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

/ / c o u t << remove << e n d l ;

318
319
i f ( ! l >v i s i t e d S t a r t P o i n t )
320
321
{
l >v i s i t e d = f a l s e ; / / a l l o w t h i s l i n e t o be v i s i s t e d a g a i n f o r i t s s t a r t 322
point
}
/ / check i f i t s f i r s t i n the edge l i s t .
i f ( e d g e L i s t . i s R o o t ( l >i d ) )
{
/ / c o u t << Drawing L i n e << e n d l ;

if

it is ,

i t s VISIBLE

i f ( visual )
img . d r a w l i n e ( c e n t e r >x , c e n t e r >y , p>x , p>y , BLUE ) ;

/ / remove
/ / c o u t << V alue : << l >v a l u e ( ) << << l >i d << e n d l ;
e d g e L i s t . remove ( l >v a l u e ( ) , l >i d ) ;
i f ( visual )
img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , WHITE) ;

}
e l s e / / add i t t o e d g e l i s t
{
/ / c o u t << add << e n d l ;
l >v i s i t e d = t r u e ; / / mark i t a s h a v i n g been v i s i t e d somewhere
l >v i s i t e d S t a r t P o i n t = t r u e ; / / mark i t a s h a v i n g f o u n d t h e f i r s t v e r t e x
/ / S t o r e d i s t a n c e o f l i n e from c e n t e r
l >d i s t = d i s t a n c e ( p , c e n t e r ) ;
e d g e L i s t . add ( l ) ;
/ / c h e c k i f i t s f i r s t i n t h e e d g e l i s t . i f i t i s , i t s VISIBLE
i f ( e d g e L i s t . i s R o o t ( l >i d ) )
{
/ / c o u t << Drawing L i n e << e n d l ;
i f ( visual )
img . d r a w l i n e ( c e n t e r >x , c e n t e r >y , p>x , p>y , BLUE ) ;
}

i f ( visual )
img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , GREEN) ;

i f ( visual )
img . d r a w c i r c l e ( p>x , p>y , 5 , GREY) ;
// debug
/ / c o u t << Edge L i s t : ;
// edgeL ist . p r i n tA ll ( ) ;
// an gleL is t . p r i ntA ll ( ) ;
/ / c o u t << e n d l << e n d l ;
if ( live)
{
d i s p . d i s p l a y ( img ) ;
// u sleep ( 11000) ;
// s leep ( 1) ;
}

}
/ / c o u t << b r e a k i n g << e n d l ;
/ / br eak ;
if ( live)
{

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

Page 6 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

// u sleep ( 11000) ;
d i s p . d i s p l a y ( img ) ;

385
386
387
}
/ / br eak ;
388
// img . f i l l ( 2 0 ) ;
389
/ / c o u t << o u t e r << e n d l ;
390
391
}
392
i f ( visual )
393
394
{
395
/ / Redraw o b s t a c l e l i n e s j u s t f o r f u n :
f o r ( i n t i = 0 ; i < s e g ; ++i )
396
397
{
398
l = segs [ i ] ;
399
img . d r a w l i n e ( l >a>x , l >a>y , l >b>x , l >b>y , WHITE) ;
400
img . d r a w c i r c l e ( l >a>x , l >a>y , 2 , WHITE) ;
401
402
img . d r a w c i r c l e ( l >b>x , l >b>y , 2 , WHITE) ;
403
}
404
d i s p . d i s p l a y ( img ) ;
405
406
img . s a v e ( r e s u l t . png ) ; / / s a v e t h e image
407
408
}
409
c o u t << s e g << , << a t o m i c << e n d l ;
410
411
412
i f ( visual )
413
{
414
/ / Show window u n t i l u s e r i n p u t :
415
while ( ! disp . i s c l o s e d ( ) ) {
416
i f ( d i s p . is keyESC ( ) )
br eak ;
417
d i sp . wait ( ) ;
418
419
}
420
}
421
422
/ / Garabage c o l l e c t
423
// d el ete [ ] segs ;
424
// f r ee ( segs ) ;
425
}
426
427
//
428
/ / C a l c u l a t e A ngle Btw 2 V e c t o r s
429
//
430
d o u b l e v e c t o r s A n g l e ( i n t x , i n t y , i n t b as e x , i n t b a s e y )
431
{
432
/ / C o n v e r t i n p u t p o i n t x & y t o be v e c t o r s r e l a t i v e t o b a s e p o i n t
433
d o u b l e x2 = d o u b l e ( x b a s e x ) ;
434
d o u b l e y2 = d o u b l e ( y b a s e y ) ;
435
436
/ / Hard c o d e s c a n l i n e t o p o i n t r i g h t :
437
d o u b l e x1 = s q r t ( x2 x2 + y2 y2 ) ; / / make i t w i t h r a t i o ?
438
d o u b l e y1 = 0 . 0 ;
439
440
/ / c o u t << x1 : << x1 << y1 : << y1 << e n d l ;
441
/ / c o u t << x2 : << x2 << y2 : << y2 << e n d l ;
442
double s t u f f = (
( x1 x2 ) +(y1 y2 )
) / ( s q r t ( x1 x1+y1 y1 )
s q r t ( x2 x2+y2 y2 ) ) ; 443
444
/ / c o u t << S t u f f : << s t u f f << e n d l ;
445
446
// Calculate angle :
447
double r e s u l t = ac os ( s t u f f ) ;
448
/ / c o u t << R e s u l t : << r e s u l t << e n d l ;
449
450
/ / Now add PI i f b e l o w m i d d l e l i n e :
451
i f ( y >= b a s e y )
452
r e s u l t = 2 M PI r e s u l t ;

Page 7 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

/ / c o u t << R e s u l t : << r e s u l t 1 8 0 / M PI << d e g r e e s << e n d l ;


r etur n r esu l t ;
}
//
/ / D i s t a n c e Btw 2 P o i n t s
//
d o uble d i s t a n c e ( P oint a , Point b )
{
r e t u r n s q r t ( pow ( b>x a>x , 2 . 0 ) + pow ( b>y a>y , 2 . 0 ) ) ;
}

453
454
455
456
457
458
459
460
461
462
463
464

../visibility graph/vgraph.cpp

Page 8 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

skiplist.h
1
2
3
4
2/2/2012
5
6
Implementation o f Skip L i s t s
7
/
8
9
#i n c l u d e <math . h>
10
#i n c l u d e <i o s t r e a m >
11
#i n c l u d e < c s t d l i b >
12
#i n c l u d e node . h
13
//#i n c l u d e p o i n t . h
14
u s i n g namespace s t d ;
15
16
/ /
17
/ / Skip L i s t C l a s s
18
/ /
19
t e m p l a t e < c l a s s T>
20
cla ss sk i pl ist {
21
/ / used f o r t e s t i n g
22
public :
23
i n t maxLevel ;
24
25
pr iv ate :
26
node<T> r o o t ;
27
28
/ / 29
/ / Get Random L e v e l
30
/ / 31
i n t getRandL evel ( )
32
{
33
i n t r andResult = 1 ;
34
int lev el = 0;
35
w hil e ( r andResult )
36
{
37
38
r a n d R e s u l t = rand ( ) % 2 ;
39
i f ( r andResult )
40
{
41
++l e v e l ;
42
}
43
44
i f ( l e v e l > maxLevel )
45
{
46
r a n d R e s u l t = 0 ; / / t o end t h e w h i l e l o o p
47
}
48
}
49
r etur n l e v e l ;
50
51
}
52
/ / 53
/ / C r e a t e New Node
54
/ / 55
node<T> c r e a t e N o d e ( i n t l e v e l , i n t h e i g h t , T d a t a )
56
{
57
/ / Check i f we a r e b e l o w l e v e l 0
58
i f ( l e v e l < 0)
59
{
60
r e t u r n NULL ;
61
}
62
e l s e / / make a new node b e l o w
63
{
64
node<T> newNode = new node<T>() ;
65
newNode> l e v e l = l e v e l ;
66
/ S k i p L i s t
CSCI 5454 A l g o r i t h m s
Dave Coleman | d a v i d . t . c o l e m a n @ c o l o r a d o . edu

Page 9 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

67
68
69
70
71
}
72
}
73
74
public :
75
76
// Constr uctor :
77
sk iplist ()
78
{
79
r o o t = NULL ;
80
maxLevel = 0 ;
81
82
s r a n d ( t i m e (NULL) ) ; / / s e e d t h e random g e n e r a t o r
83
}
84
/ / 85
/ / ADD
86
/ / 87
v o i d add ( T d a t a )
88
{
89
/ / c o u t << ADD: ;
90
// d a t a . p r i n t ( ) ;
91
92
/ / S p e c i a l C a s e s
93
94
i f ( ! r o o t ) / / no r o o t h a s been e s t a b l i s h e d y e t
95
96
{
97
r o o t = cr eateN o de ( 0 , 0 , data ) ;
r etur n ;
98
99
}
100
i f ( r o o t >data>v a l u e ( ) > data>v a l u e ( ) ) / / new v a l u e g o e s b e f o r e r o o t
101
102
{
103
T t e m p d a t a = r o o t >d a t a ;
104
node<T> n = r o o t ;
105
f o r ( i n t l = maxLevel ; l >= 0 ; l )
106
107
{
108
a t o m i c += 1 ;
109
/ / c h a n g e t h e r o o t t o t h e new v a l u e
n>d a t a = d a t a ;
110
n = n>b e l o w ;
111
112
}
113
data = temp data ;
114
}
115
/ / R e g u l a r i n s e r t a f t e r r o o t
116
117
/ / D e t e r m i n e what l e v e l t h i s new node w i l l be a t
118
i n t l e v e l = getRandL evel ( ) ;
119
120
/ / I f new node i s a t w h o l e new l e v e l , go ahead and u p d a t e r o o t node t o be h i g h e r
121
i f ( l e v e l > maxLevel )
122
123
{
124
maxLevel ++;
node<T> newRoot = new node<T>() ;
125
newRoot>d a t a = r o o t >d a t a ;
126
newRoot>n e x t = NULL ; newRoot>b e l
127
ow = r o o t ;
128
newRoot> l e v e l = maxLevel ;
129
r o o t = newRoot ;
130
}
131
132
/ / C r e a t e t h e new node
133
node<T> newNode = c r e a t e N o d e ( l e v e l , l e v e l , d a t a ) ;
134
newNode>n e x t = NULL ;
newNode>b e l o w = c r e a t e N o d e (
newNode>h e i g h t = h e i g h t ;
newNode>d a t a = d a t a ;
r e t u r n newNode ;

l e v e l 1 , height , data ) ;

Page 10 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

135
136
137
138
/ / Loop down t h r o u g h a l l l e v e l s
139
140
f o r ( i n t l = maxLevel ; l >= 0 ; l )
141
{
142
a t o m i c += 1 ;
/ / move f o r w a r d u n t i l we h i t a v a l u e g r e a t e r than o u r s
143
144
w h i l e ( i >n e x t != NULL )
145
{
146
a t o m i c += 1 ;
147
i f ( i >next>data>v a l u e ( ) > data>v a l u e ( ) ) / / i n s e r t b e f o r e i . n e x t
148
{
149
br eak ;
150
}
151
i = i >n e x t ;
152
}
153
154
/ / Check i f we s h o u l d add a p o i n t e r a t t h i s l e v e l
155
i f ( l <= l e v e l )
156
{
157
newNode>n e x t = i >n e x t ;
158
i >n e x t = newNode ;
159
160
/ / Now move t h e new node p o i n t e r one l e v e l down :
161
newNode = newNode>b e l o w ;
162
}
163
164
/ / Always move t h e i node p o i n t e r one l e v e l down :
165
i = i >b e l o w ;
166
}
167
168
}
/ / 169
/ / Find
170
/ / 171
b ool f i n d ( dou bl e x )
172
173
{
174
node<T> i = r o o t ;
175
/ / S p e c i a l c a s e : s k i p l i s t i s empty
176
i f ( ! r oot )
177
178
{
179
r etur n f a l s e ;
180
}
181
/ / S p e c i a l c a s e : c heck r o o t
182
183
i f ( r o o t >data>v a l u e ( ) == x )
184
{
185
r etur n tr ue ;
186
}
187
f o r ( i n t l = maxLevel ; l >= 0 ; l )
188
189
{
190
a t o m i c += 1 ;
/ / move f o r w a r d u n t i l we h i t a v a l u e g r e a t e r than o u r s
191
192
w h i l e ( i >n e x t != NULL )
193
{
194
a t o m i c += 1 ;
195
if (
i >n e x t >data>v a l u e ( ) > x ) / / x i s n o t f o u n d on t h i s l e v e l
196
{
197
br eak ;
198
}
199
e l s e i f ( i >next>data>v a l u e ( ) == x ) / / b i n g o !
200
{
201
r etur n tr ue ;
202
}
/ / Now add t h e node t o t h e l i s t
node<T> i = r o o t ;

Page 11 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

203
204
205
}
206
/ / Always move t h e i node<T> p o i n t e r one l e v e l down :
207
208
i = i >b e l o w ;
209
}
210
r etur n f a l s e ;
211
212
}
/ / 213
/ / REMOVE
214
/ / t h e i d i s t o c o n f i r m t h e c o r r e c t node , j u s t i n c a s e x i s n o t u n i q u e
215
/ / 216
b o o l remove ( d o u b l e x , i n t i d )
217
218
{
219
node<T> i = r o o t ;
220
/ / S p e c i a l c a s e : remove r o o t
2
21
222
i f ( r o o t >data>v a l u e ( ) == x && r o o t >data>i d == i d )
223
{
224
/ / Get l e v e l 0 o f r o o t
225
f o r ( i n t l = r o o t > l e v e l ; l > 0 ; l )
226
{
227
a t o m i c += 1 ;
/ / c o u t << L e v e l << l << e n d l ;
228
229
i = i >b e l o w ;
230
}
231
/ / Check i f t h e r e a r e any more n o d e s
232
233
i f ( ! i >n e x t ) / / t h e s k i p l i s t i s empty
234
{
235
r o o t = NULL ;
maxLevel = 0 ;
236
237
r etur n tr ue ;
238
239
}
240
241
/ / Change v a l u e o f r o o t t o n e x t node
242
node<T> n = r o o t ;
243
node<T> nextNode = i >n e x t ;
244
f o r ( i n t l = maxLevel ; l >= 0 ; l )
245
246
{
247
a t o m i c += 1 ;
248
/ / c h a n g e t h e r o o t t o t h e new v a l u e
249
n>d a t a = nextNode>d a t a ;
250
251
/ / update ne x t p o i n t e r i f t h e ne x t n e xt e x i s t s
252
i f ( n>n e x t )
253
{
254
n>n e x t = n>next>n e x t ;
255
}
256
257
/ / Move down t o n e x t l e v e l
258
n = n>b e l o w ;
259
}
260
261
r etur n tr ue ;
262
}
263
264
/ / Normal c a s e : remove a f t e r r o o t
265
b o o l found = f a l s e ;
266
f o r ( i n t l = maxLevel ; l >= 0 ; l )
267
268
{
269
a t o m i c += 1 ;
270
/ / move f o r w a r d u n t i l we h i t a v a l u e g r e a t e r than o u r s
i = i >n e x t ;

Page 12 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

w h i l e ( i >n e x t != NULL )
{
a t o m i c += 1 ;
/ / remove t h i s one , c o n f i r m e d by i d
i f ( i >next>data>v a l u e ( ) == x && i >next>data>i d == i d )
{
found = t r u e ;

271
272
273
274
275
276
277
278
// pass thr ough the p oi n t e r i f e x i s t s
279
280
i f ( i >n e x t )
281
{
282
i >n e x t = i >next>n e x t ;
283
}
284
else
285
{
286
i >n e x t = NULL ;
287
}
288
br eak ;
289
}
290
e l s e i f ( i >next>data>v a l u e ( ) > x ) / / x i s n o t f o u n d on t h i s l e v e l
291
{
292
br eak ;
293
}
294
i = i >n e x t ;
295
296
}
297
298
/ / Always move t h e i node p o i n t e r one l e v e l down :
299
i = i >b e l o w ;
300
}
301
302
r e t u r n found ;
303
}
/ / 304
/ / POP FROM FRONT
305
/ / 306
T pop ( )
307
308
{
309
node<T> i = r o o t ;
310
/ / S t o r e t h e f i r s t i t e m on t h e l i s t t h a t we want t o l a t e r r e t u r n
311
312
T r e s u l t = r o o t >d a t a ;
313
/
314
c o u t << POP WITH VALUE: << r o o t >v a l u e << ;
315
r esult . print ( ) ;
c o u t << e n d l ;
316
317
/
318
/ / Check i f s k i p l i s t i s empty
319
i f ( ! r oot )
320
321
{
322
c o u t << An e r r o r h a s o c c u r e d : s k i p l i s t i s empty ;
ex it ( 1) ;
323
324
}
325
/ / Get l e v e l 0 o f r o o t
326
327
f o r ( i n t l = r o o t > l e v e l ; l > 0 ; l )
328
{
329
a t o m i c += 1 ;
330
i = i >b e l o w ;
331
}
332
/ / Check i f t h e r e a r e any more n o d e s
333
334
i f ( ! i >n e x t ) / / t h e s k i p l i s t i s empty
335
{
336
r o o t = NULL ;
maxLevel = 0 ;
337
338

Page 13 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

339
340
341
/ / Change v a l u e o f r o o t t o n e x t node
342
343
node<T> n = r o o t ;
344
node<T> nextNode = i >n e x t ;
345
f o r ( i n t l = maxLevel ; l >= 0 ; l )
346
347
{
348
a t o m i c += 1 ;
/ / c h a n g e t h e r o o t t o t h e new v a l u e
349
350
n>d a t a = nextNode>d a t a ;
351
/ / update ne x t p o i n t e r i f t h e ne x t n e xt e x i s t s
352
353
i f ( n>n e x t )
354
{
355
n>n e x t = n>next>n e x t ;
356
}
357
358
/ / Move down t o n e x t l e v e l
359
n = n>b e l o w ;
360
}
361
362
363
r etur n r esu l t ;
364
}
365
/ /
366
/ / I s Root
/ / 367
bool isR oot ( i n t id )
368
369
{
370
i f ( ! r o o t ) / / t h e r e i s no r o o t !
371
372
{
373
s t d : : c o u t << t h e r e i s no r o o t ! << s t d : : e n d l ;
r etur n f a l s e ;
374
375
}
376
r e t u r n ( r o o t >data>i d == i d ) ;
377
}
/ / 378
/ / PRINT ALL
379
/ / 380
v oid p r i n t A ll ( )
381
382
{
383
s t d : : c o u t << s t d : : e n d l << LIST << s t d : : e n d l ;
384
/ / S p e c i a l c a s e : s k i p l i s t i s empty
385
i f ( ! r oot )
386
387
{
388
s t d : : c o u t << << s t d : : e n d l ;
389
r etur n ;
390
}
391
node<T> i = r o o t ;
392
393
/ / Get l e v e l 0 o f r o o t
394
395
f o r ( i n t l = r o o t > l e v e l ; l > 0 ; l )
396
{
397
/ / c o u t << L e v e l << l << ;
398
// i . data . p r i n t ( ) ;
/ / c o u t << e n d l ;
399
400
i = ( i . b el ow ) ;
401
}
402
/ / s t d : : c o u t << we a r e on l e v e l << i . l e v e l << s t d : : e n d l ;
403
404
/ / Hack : u p d a t e r o o t 0 l e v e l w i t h maxLevel c ount , b e c a u s e we don t u p d a t e t h i s
405
/ / when g r o w i n g r o o t l e v e l s i z e
406
i . h e i g h t = maxLevel ;
r etur n r esu l t ;

Page 14 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

i n t counter = 0;
b o o l done = f a l s e ;
w h i l e ( ! done )
{
s t d : : c o u t << c o u n t e r ;
f o r ( i n t l = i . h e i g h t ; l >= 0 ; l )
{
s t d : : c o u t << | ;
}
s t d : : c o u t << << i . data>v a l u e ( ) << ;
i . data>p r i n t ( ) ;
c o u n t e r ++;
i f ( i . next )
{
node<T> i i = i . n e x t ;
i = ii ;
}
else
{
done = t r u e ;
}
}
s t d : : c o u t << << s t d : : e n d l << s t d : : e n d l ;
}
};

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437

../visibility graph/skiplist.h

Page 15 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

node.h
#i n c l u d e l i n e . h

1
2
3

//

/ / Node C l a s s
4
//
5

t e m p l a t e < c l a s s T>
c l a s s node {
public :
node b e l o w ; / / node b e l o w i n t o w e r
node n e x t ; / / n e x t node i n s k i p l i s t
i n t l e v e l ; / / l e v e l o f t h i s c u r r e n t node
i n t h e i g h t ; / / f u l l number o f l e v e l s i n t o w e r
T data ;
};

6
7
8
9
10
11
12
13
14

../visibility graph/node.h

Page 16 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

line.h
1
2
3
#i n c l u d e <i o s t r e a m >
4
#i n c l u d e p o i n t . h
5
#i n c l u d e g e o m e t r y . h
6
#i n c l u d e <cmath>
7
8
c l a s s L i n e : p u b l i c Geometry
9
{
10
public :
11
P oint a ;
12
P oint b ;
13
b o o l v i s i t e d S t a r t P o i n t ; / / h a s t h e b a s e / sweep l i n e c r o s s e d a t l e a s t one o f
14
// the v e r t i c i e s ?
15
b o o l v i s i t e d ; / / h a s t h e sweep l i n e been on t h e l i n e ( a s i n , maybe i t was i n i t on i t ) 16
17
i nt id ;
18
d o u b l e d i s t ; / / d i s t a n c e from c e n t e r
19
d o u b l e t h e t a c a c h e ; / / u s e d f o r d e c i d i n g i f t h e d i s t c a c h e n e e d s t o be r e f r e s h e d
20
d o u b l e m; / / s l o p e o f l i n e
21
d o u b l e y i n t e r c e p t ; / / yi n t e r c e p t o f l i n e
22
23
L ine ( ) ;
24
L ine ( i n t x1 , i n t y1 , i n t x2 , i n t y 2 ) ;
25
L ine ( ) ;
26
v i r t u a l v oid p r i n t ( ) ;
27
v i r t u a l double v alue ( ) ;
28
29
v oid updat eCalc s ( ) ;
30
v oid d istan ce ( ) ;
31
v o i d c e n t e r i n t e r c e p t ( d o u b l e &x i , d o u b l e &y i ) ;
32
};
33
34
35
/ / T h i s g l o b a l n e e d s t o be v i s i b l e t o c l a s s e s :
36
ex t er n Point c en t er ;
37
e x t e r n L ine c e n t e r l i n e ;
38
e x t e r n d ouble atomic ;
39
40
#e n d i f
41
#i f n d e f LINE H INCLUDED
#d e f i n e LINE H INCLUDED

../visibility graph/line.h
line.cpp
#i n c l u d e l i n e . h
P oint c e n t e r ;
L ine c e n t e r l i n e ;
d o uble atomic ;
u s i n g namespace s t d ;
L ine : : L ine ( )
{
c o u t << You a r e c a l l i n g t h e f u n c t i o n wrong ;
ex it ( 0) ;
}
L i n e : : L i n e ( i n t x1 , i n t y1 , i n t x2 , i n t y2 )
{
/ / Order a and b s u c h t h a t a . x > b . x
i f ( x1 > x2 )
{
a = new P o i n t ( x1 , y1 ) ;
b = new P o i n t ( x2 , y2 ) ;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Page 17 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

22
23
24
25
26
27
/ / Change ID
28
s t a t ic i nt id cou nter = 0;
29
i d = i d c o u n t e r ++;
30
31
/ / Keep t r a c k o f i t s v i s i t e d h i s t o r y
32
v isited = f alse ;
33
v isitedStar tP oint = f al se ;
34
35
/ / c o u t << LINE << e n d l ;
36
u pd at eCalcs ( ) ;
37
38
/ / c o u t << LINE << e n d l ;
39
40
/ / Used f o r c h e c k i n g i f we need t o r e f r e s h o u r d i s t a n c e amount
41
t h e t a c a c h e = 3 M PI ; / / some a n g l e b i g g e r than 2 PI , aka INF
42
// distance ( ) ;
43
44
/ / c o u t << END LINE \n << e n d l ;
45
}
46
L ine : : L ine ( )
47
{
48
// d el ete a ;
49
// d el ete b ;
50
}
51
v oid L ine : : p r i n t ( )
52
{
53
c o u t << L i n e : x1 : << a>x << y1 : << a>y << x2 : << b>x
54
<< y2 : << b>y << \ t ID : << i d << e n d l ;
55
}
56
double L ine : : v alue ( )
57
{
58
/ / c a l c u l a t e d i s t a n c e from m i d p o i n t a t a g i v e n t h e t a ,
59
// with r e s e p c t to the b a s e l i n e
60
61
i f ( t h e t a c a c h e != c e n t e r >t h e t a ) / / c h e c k i f o u r c a c h e d v e r s i o n i s s t i l l f r e s h enough62
{
63
/ / c o u t << R e c a l c u l a i n g d i s t a n c e f o r l i n e << i d << e n d l ;
64
distance ( ) ;
65
}
66
67
r etur n d i st ;
68
}
69
v o i d L ine : : updat eC alc s ( )
70
{
71
/ / Find S l o p e and yi n t e r c e p t o f t h i s l i n e f o r f u t u r e d i s t a n c e c a l c u l a t i o n s
72
d o u b l e denom = ( b>x a>x ) ;
73
i f ( denom == 0 )
74
{
75
/ / c o u t << T h i s program d o e s n o t s u p p o r t p e r f e c t l y v e r t i c l e l i n e s . << e n d l ;
76
// ex it ( 0) ;
77
78
// Per tur b :
79
//
b>x = b>x + 1 ;
80
denom = 0 . 0 0 0 0 0 0 0 0 1 ; / / ( b>x a>x ) ;
81
}
82
m = ( b>y a>y ) /denom ;
83
84
/ / c o u t << m << M << e n d l ;
85
86
y i n t e r c e p t = a>y m a>x ;
87
/ / c o u t << y i n t e r c e p t << m << e n d l ;
88
}
89
else
{
b = new P o i n t ( x1 , y1 ) ;
a = new P o i n t ( x2 , y2 ) ;
}

Page 18 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

v oid L ine : : d i s ta n c e ( )
{
/ / F i r s t f i n d t h e i n t e s e c t i o n o f t h i s l i n e and t h e sweep l i n e :
double x i ;
double y i ;
c e n t e r i n t e r c e p t ( xi , y i ) ;
/ / c o u t << The i n t e r c e p t i s x : << x i << y : << y i << e n d l ;
/ / c o u t << M: << m << b : << y i n t e r c e p t << e n d l ;
/ / Now f i n d t h e d i s t a n c e betw een t h e s e two l i n e s :
d i s t = s q r t ( pow ( c e n t e r >x x i , 2 . 0 ) + pow ( c e n t e r >y y i , 2 . 0 )

);

/ / c o u t << D i s t a n c e : << d i s t << e n d l << e n d l ;


t h e t a c a c h e = c e n t e r >t h e t a ;

v o i d L i n e : : c e n t e r i n t e r c e p t ( d o u b l e &x i , d o u b l e &y i )
{
x i = d o u b l e ( y i n t e r c e p t c e n t e r l i n e >y i n t e r c e p t ) / d o u b l e ( c e n t e r l i n e >m m ) ;
y i = m x i + y i n t e r c e p t ;
}

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

../visibility graph/line.cpp

Page 19 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

point.h
#i f n d e f POINT H INCLUDED
#d e f i n e POINT H INCLUDED
#i n c l u d e <i o s t r e a m >
#i n c l u d e g e o m e t r y . h
c l a s s P o i n t : p u b l i c Geometry
{
public :
int x ;
int y ;
v oid par entL ine ;
i n t i d ; / / f o r removing , comparing , e t c
d o u b l e t h e t a ; / / a n g l u l a r amount from b a s e l i n e
P oint ( ) ;
P oint ( i n t

x1 , i n t

y1 ) ;

v i r t u a l v oid p r i n t ( ) ;
v i r t u a l double v alue ( ) ;
};
#e n d i f

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

../visibility graph/point.h
point.cpp
#i n c l u d e p o i n t . h

P oint : : Point ( )
{
s t a t ic i nt id cou nter = 0;
i d = i d c o u n t e r ++;
}
P oint : : Point ( i n t x1 , i n t y 1 )
{
x = x1 ;
y = y1 ;
P oint ( ) ;
}
v oi d Point : : p r i n t ( )
{
s t d : : c o u t << P o i n t x : << x << y : << y << \ t ID : << i d << s t d : : e n d l ;
}
d ouble Point : : v al u e ( )
{
/ / t h i s i s t h e a n g u l a r d i s t a n c e from t h e b a s e l i n e
/ / f o r p o i n t . cpp , we j u s t c a c h e t h e i n i t i a l c a l c u l a t i o n
r etur n theta ;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

../visibility graph/point.cpp

Page 20 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

geometry.h
#i f n d e f GEOMETRY H INCLUDED
#d e f i n e GEOMETRY H INCLUDED
c l a s s Geometry
{
public :
/ / i n t i d ; / / f o r removing , comparing , e t c
v i r t u a l v oid p r i n t ( ) = 0;
v i r t u a l double v alue ( ) = 0 ;
};
#e n d i f

1
2
3
4
5
6
7
8
9
10
11
12
13
14

../visibility graph/geometry.h

Page 21 of 22

Dave Coleman

CSCI 5454 (Prof. Clauset 4:00 MW): Visibility Graph

Matlab plot.m Used For Generating Plots


clear
clc
data = c s v r ea d ( data . c v s )
n = data ( : , 1 )
logger 1 = 50.( n .2) . log ( n ) ;
logger 2 = 25.( n .2) . log ( n ) ;
l o g l o g ( d a t a ( : , 1 ) , d a t a ( : , 2 ) , bo , . . .
d at a ( : , 1 ) , l o g g e r 1 , k : , da ta ( : , 1 ) , l o g g e r 2 , k : )
s e t ( gca , F o n t S i z e , 1 4 )
l e g e n d ( Number o f l o o k u p s , O( n 2 l o g n ) , L o c a t i o n , NorthWest )
x l a b e l ( Input s i z e , n )
y l a b e l ( Number o f o p e r a t i o n s , T )
t i t l e ( Atomic O p e r a t i o n s o f Lee V i s i b i l i t y Graph A l g o r i t h m ) ;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

../visibility graph/plot.m
Runtime Data Restuls
1
2
3
4
5
6

9 ,6026
25 ,62585
1 0 0 , 1 . 4 2 3 1 3 e +06
2 8 9 , 1 . 4 7 7 5 1 e +07
9 6 1 , 2 . 3 4 0 2 7 e +08
3 1 3 6 , 2 . 9 1 4 e +09

../visibility graph/data.cvs

Page 22 of 22

You might also like