Hidden_Line_Problem/Schrick-Noah_CS-7353_HW4.tex
2022-03-09 22:15:04 -06:00

158 lines
7.7 KiB
TeX

\documentclass{article}
\usepackage{graphicx}
\graphicspath{ {./images/} }
\usepackage[utf8]{inputenc}
\usepackage{float}
\usepackage{indentfirst}
\setlength{\parskip}{\baselineskip}%
\title{CS 7353: Analysis of Algorithms Homework 4: Visible Lines Problem}
\author{Noah Schrick}
\date{March 8, 2022}
\begin{document}
\maketitle
\tableofcontents
\section{Problem Introduction}
The Hidden Surface Problem is widely used in computer graphics. When displaying images,
not all images should be visible (for example, if one object is in front of another).
To avoid overlapping images from being displayed and causing collisions, computations are
performed to remove all or parts of an object from the field of vision.
This problem is a simplified version focusing on linear lines in a 2D plane.
Rather than handling shifting
perspectives, this problem will be further simplified to
focus on the perspective as looking down from y=$\infty$.
The problem statement can be defined as follows:
You are given n nonvertical lines in the plane, labeled $L_{1}$,...,$L_{n}$,
with the ith line specified by the equation y=$a_{i}$x+$b_{i}$.
We will make the assumption that no three of the lines all meet at a single
point. We say line $L_{i}$ is uppermost at a given x-coordinate $x_{0}$ if its y-coordinate
at $x_{0}$ is greater than the y-coordinates of all the other lines at
$x_{0}$: $a_{i}$$x_{0}$+$b_{i}$>$a_{j}$$x_{0}$$b_{j}$ for all
j$\not=$i.
We say line $L_{i}$ is visible if there is some x-coordinate at which
it is uppermost-intuitively, some portion of it can be seen if you look down from "y=$\infty$".
Determine which lines are visible and at which restricted domains.
\section{Program Preface}
This assignment was given with instruction to implement this in C++, or justify why Python
should be used instead. This problem was solved using C++ on a Linux system.
Attached with submission is a zip folder that contains:
\begin{itemize}
\item{A CMakeLists.txt file for compiling}
\item{An "images" folder that contains:}
\begin{enumerate}
\item{Various images included in this report}
\end{enumerate}
\item{A "src" folder that contains:}
\begin{enumerate}
\item{A Line.cpp and Line.h file for the Line class and associated functions}
\item{A HiddenLines.cpp and HiddenLines.h file for the problem instance class and
associated functions}
\item{A GNUPlot .hpp file for plotting}
\item{The main file}
\end{enumerate}
\item{A "data" folder that contains:}
\begin{enumerate}
\item{A CSV file for defining the line functions to use}
\end{enumerate}
\item{A "build" folder that contains:}
\begin{enumerate}
\item{A build.sh script to simplify the build process}
\item{A run.sh script to simplify running the program}
\item{Various CMake files}
\item{The compiled binaries for the program and associated libraries}
\end{enumerate}
\end{itemize}
This program requires the installation of GNUPlot for plotting purposes,
but modification can be performed to remove the plotting. Removing the plotting
does not alter the solution computation.
In addition, this program promises no guarantee of working on other Operating Systems -
no testing was conducted on any other platform besides the local Linux machine.
\section{Programming Approach}
\subsection{Line Class}
To aid in the derivation of the solution, the first step was to create a Line class.
This class has members of slope, y-intercept, an ID, the x-value at which visibility starts,
and the x-value at which visibility ends. The ID is associated with the order from the CSV file,
and the visibility values are both initialized to 0.
Functions included with this class are getters and setters for various members, and
operator overloads for == and $<$ to aid in the sorting of Lines based on slope when using sets.
Also included is a function to find the x-value of the intersection between two lines.
\subsection{HiddenLines Class}
A separate class was created for handling the problem space. The HiddenLines class contains
few members of its own, and is primarily function-based. The single member that this class
has is a vector of all lines for the given problem.
This class contains four functions: a function to construct the problem, a function to get
the vector of lines, a function to generate the solution, and a function to print the solution.
\subsubsection{Constructing the Problem}
For modularity, this problem uses a CSV file for constructing the problem. Any and all lines can
be stored in a CSV file in the data folder. This CSV file is of format (slope,y-intercept).
This file is read and parsed, then inserted into a set to order the lines by slope. After
all lines are imported, the set is then copied to a vector for ease of use for other functions.
Basic error checking is performed only in the sense of ensuring that there are the same number
of slopes and y-intercept entries.
\subsubsection{Generating the Solution}
This problem uses a divide-and-conquer approach. The base cases are for line vectors of size 1 or 2.
When a line vector is of size 1, it is returned with no further computation. When a line vector is
of size 2, the two lines have their slopes compared and their intersection point found. The line
with the smallest slope is visible up until the intersection point, and the line with the greater
slope is visible starting at the intersection point. The lines have their underlying visibility
range members adjusted, and they are returned to be merged with the other divided half.
The merge process walks through each halved list and compares lines between the halves.
The lines between the vectors have their slopes and intersection points compared, similar to the
aforementioned process, but a separate function for removing the invisible lines is also called
after the halves are merged. The removal process returns a new vector container that only
holds the visible lines, after further comparisons of lines and intersection points.
\subsubsection{Printing the solution} \label{sec:print}
The solution is printed by walking through the final container and printing each line's
ID, their visibility start point, and their visibility end point. If the start or end point
is the maximum or minimum value of a double, then it is converted to a string of positive
or negative infinity, respectively. In addition, GNUPlot prints the original problem space,
and the final visible lines. As a note, extra work is needed to convert the final solution
to a piecewise plot. At the current moment, all lines that are visible are printed across
the entire domain, rather than their restricted domain.
\section{Results}
Figure \ref{fig:term} shows the output of the terminal after the program completes.
This solution was manually verified with Desmos by plotting each line and comparing
their intersections. Figure \ref{fig:orig} displays the plotting of the original problem
with GNUPlot. Figure \ref{fig:sol} displays the plotting of the only visible lines, though
as mentioned in Section \ref{sec:print}, further work needs to be conducted to plot the
piecewise functions correctly.
\begin{figure}[htp]
\includegraphics[width=\linewidth]{"./images/term.png"}
\vspace{.2truein} \centerline{}
\caption{Path Walking to State 14}
\label{fig:term}
\end{figure}
\begin{figure}[htp]
\includegraphics[width=\linewidth]{"./images/orig.png"}
\vspace{.2truein} \centerline{}
\caption{Path Walking to State 14}
\label{fig:orig}
\end{figure}
\begin{figure}[htp]
\includegraphics[width=\linewidth]{"./images/sol.png"}
\vspace{.2truein} \centerline{}
\caption{Path Walking to State 14}
\label{fig:sol}
\end{figure}
\end{document}