Fix mathjax formatting and links

This commit is contained in:
Rory Healy 2024-06-12 21:46:37 +10:00
parent cd3c219180
commit a6372ac9be
Signed by: roryhealy
GPG key ID: 0A3CBDE9C2AE672F

View file

@ -22,7 +22,7 @@ Geometric data can be stored in many ways, such as a list of points, the union o
Some geometric problems require us to not only store the geometric properties such as the coordinates of points (or vertices), but also if two points are connected or if two edges bound the same region in a polygonal mesh. Such information is called topological information. Some geometric problems require us to not only store the geometric properties such as the coordinates of points (or vertices), but also if two points are connected or if two edges bound the same region in a polygonal mesh. Such information is called topological information.
There are a number of data structures that can store geometric and topological information efficiently. In this assignment, we will discuss one of those: the doubly connected edge list (DCEL). The DCEL is a data structure that enables us to store and reconstruct any planar subdivision. Now, what is a planar subdivision? Here is a graphical example but we give a more formal introduction in the [Graphs](#markdown-header-graphs) section. There are a number of data structures that can store geometric and topological information efficiently. In this assignment, we will discuss one of those: the doubly connected edge list (DCEL). The DCEL is a data structure that enables us to store and reconstruct any planar subdivision. Now, what is a planar subdivision? Here is a graphical example but we give a more formal introduction in the [Graphs](#graphs) section.
![](./images/image01.png) ![](./images/image01.png)
@ -42,7 +42,7 @@ In addition to queries, our data structure also needs to support various operati
### Graphs ### Graphs
A graph is a $G$ is a pair $G=\{V,E\}$ where $V$ is a set of *nodes* or *vertices* and $E$ is a set of edges (a binary relation on $V$). Let $V$ be a vertex. An edge $E$ can be defined as a pair of vertices, or a binary relation on $V$. Then, a graph is a $G$ is a pair $G=\{V,E\}$ where $V$ is a set of *nodes* or *vertices* and $E$ is a set of edges.
If a pair of vertices $(u,v)∈E$ is the same as the pair $(v,u)$, they are connected by an *undirected* edge $(u,v)$. The vertices are called *adjacent* to each other. If a pair of vertices $(u,v)∈E$ is the same as the pair $(v,u)$, they are connected by an *undirected* edge $(u,v)$. The vertices are called *adjacent* to each other.
@ -62,13 +62,13 @@ In this figure the vertices $a$ and $b$ are adjacent, and the edges $(c,d)$, $(d
### DCEL ### DCEL
If we were store the $x$ and $y$-coordinates of the vertices $a$ to $i$ in an array or a linked list, then we would lose all topological information, for example, that the points $c$, $d$ and $i$ form a triangle and all belong to the same face $F3$. And vice versa, we might be interested in listing all vertices in clock (or counter clock)-wise order of face $F5$. To capture this information and to answer these queries (efficiently), we need a DCEL. If we were store the $x$ and $y$ coordinates of the vertices $a$ to $i$ in an array or a linked list, then we would lose all topological information, for example, that the points $c$, $d$ and $i$ form a triangle and all belong to the same face $F3$. And vice versa, we might be interested in listing all vertices in clock (or counter clock)-wise order of face $F5$. To capture this information and to answer these queries (efficiently), we need a DCEL.
A DCEL is a data structure that represents (stores) the vertices, edges, and faces of our planar graph (subdivision). The reason we do not simply use a doubly linked list, for example, to store a subdivision is that for a given edge $e$, there are two possible next edges because each edge is incident to two faces. For example, the edge $(d, g)$ is incident to $F4$ and $F5$. In other words: there are two possible next edges. The key idea is to split each edge into two half edges, one where we traverse a face in a clockwise direction and one where we traverse the other face in a counter clockwise direction. Once we agree on an orientation (clockwise or counter clockwise), each face is bounded by unique half edges (i.e. each half edge is incident to exactly one face). The half edges that are incident with the same undirected edge are sometimes called *twins*. The figure below shows the twins $h_{45}$ and $h_{54}$ for the undirected edge $(d, g)$. If we agree on clockwise orientation then the half edge $h_{45}$ belongs exclusively to face $F4$ and $h_{54}$ to $F5$. A DCEL is a data structure that represents (stores) the vertices, edges, and faces of our planar graph (subdivision). The reason we do not simply use a doubly linked list, for example, to store a subdivision is that for a given edge $e$, there are two possible next edges because each edge is incident to two faces. For example, the edge $(d, g)$ is incident to $F4$ and $F5$. In other words: there are two possible next edges. The key idea is to split each edge into two half edges, one where we traverse a face in a clockwise direction and one where we traverse the other face in a counter clockwise direction. Once we agree on an orientation (clockwise or counter clockwise), each face is bounded by unique half edges (i.e. each half edge is incident to exactly one face). The half edges that are incident with the same undirected edge are sometimes called *twins*. The figure below shows the twins $h_{45}$ and $h_{54}$ for the undirected edge $(d, g)$. If we agree on clockwise orientation then the half edge $h_{45}$ belongs exclusively to face $F4$ and $h_{54}$ to $F5$.
![](./images/image03.png) ![](./images/image03.png)
For all details of the DCEL, see [Implementation Details](#markdown-header-implementation-details). For all details of the DCEL, see the [Implementation Details](#implementation-details) section.
## Your Task ## Your Task
@ -82,15 +82,15 @@ The second file will contain a list of points, one per line, of the initial poly
If the original polygon was the list of points $\{(0, 0), (0, 2), (2, 2), (2, 0)\}$, this would generate 4 edges: If the original polygon was the list of points $\{(0, 0), (0, 2), (2, 2), (2, 0)\}$, this would generate 4 edges:
$$ ```math
\{(0, 0) \rightarrow (0, 2), (0, 2) \rightarrow (2, 2), (2, 2) \rightarrow (2, 0), (2, 0) \rightarrow (0, 0)\} \{(0, 0) \rightarrow (0, 2), (0, 2) \rightarrow (2, 2), (2, 2) \rightarrow (2, 0), (2, 0) \rightarrow (0, 0)\}
$$ ```
![](./images/image04.png) ![](./images/image04.png)
On standard input, you will receive a list of pairs of integers. Each pair represents a split which should occur in the polygon. This split should bisect the two edges, beginning in the middle of the first edge and finishing at the middle of the second edge. On standard input, you will receive a list of pairs of integers. Each pair represents a split which should occur in the polygon. This split should bisect the two edges, beginning in the middle of the first edge and finishing at the middle of the second edge.
For the polygon above, the input $\{(2, 3)\}$ would generate two additional points. The first point bisects Edge 2 at position $(2, 1)$ and the second point bisects Edge 3 at position $(0, 1)$. Those two new points are connected with an additional edge. This new edge is also numbered sequentially as Edge 4. The starting and ending edge are now split and 2 new edges are added (Edge 5 and Edge 6). Further details on the numbering of these splits are given in the [Implementation Details](#markdown-header-implementation-details) section, but the result of this is shown here: For the polygon above, the input $\{(2, 3)\}$ would generate two additional points. The first point bisects Edge 2 at position $(2, 1)$ and the second point bisects Edge 3 at position $(0, 1)$. Those two new points are connected with an additional edge. This new edge is also numbered sequentially as Edge 4. The starting and ending edge are now split and 2 new edges are added (Edge 5 and Edge 6). Further details on the numbering of these splits are given in the [Implementation Details](#implementation-details) section, but the result of this is shown here:
![](./images/image05.png) ![](./images/image05.png)
@ -102,7 +102,7 @@ The third file will be used to output the result of applying all splits. After a
## Datasets ## Datasets
The watchtower data filename will be the first argument to your program. A sample dataset can be seen in the [data](../data) directory. The watchtower data filename will be the first argument to your program. A sample dataset can be seen in the [data](../test/data) directory.
The postcode data initially comes from the Department of Environment, Land, Water and Planning (ANZVI0803003025), and has been combined with population data from the [2016 Census](https://www.abs.gov.au/census/find-census-data/datapacks?release=2016) and names generated using the Python [names](https://pypi.org/project/names/) package, which uses 1990 US Census data. The postcode data initially comes from the Department of Environment, Land, Water and Planning (ANZVI0803003025), and has been combined with population data from the [2016 Census](https://www.abs.gov.au/census/find-census-data/datapacks?release=2016) and names generated using the Python [names](https://pypi.org/project/names/) package, which uses 1990 US Census data.
@ -170,7 +170,7 @@ Splits should be read into your program from standard input. Two sample sets of
- endEdge - The final edge of the split (integer) - endEdge - The final edge of the split (integer)
The fields **startEdge** and **endEdge** are integers and correspond to the edges explained in the [Implementation Details](#markdown-header-implementation-details) section. The fields **startEdge** and **endEdge** are integers and correspond to the edges explained in the [Implementation Details](#implementation-details) section.
The two values are split by a space and pairs are given one per line. The two values are split by a space and pairs are given one per line.
@ -186,15 +186,15 @@ Your `Makefile` should produce an executable program called `voronoi1`. This pro
Your `voronoi1` program should: Your `voronoi1` program should:
- Read the data from the data file specified in the command line argument. The data from the csv should be stored in a dynamic array of pointers to structs. Datatypes for each field should be consistent with those in the [Datasets](#markdown-header-datasets) section. - Read the data from the data file specified in the command line argument. The data from the csv should be stored in a dynamic array of pointers to structs. Datatypes for each field should be consistent with those in the [Datasets](#datasets) section.
- Construct the initial polygon from the second file. The points from this file should be used to construct a single Doubly Connected Edge List representing the inside of this polygon, with the first edge in this Doubly Connected Edge List stored in a dynamic array. - Construct the initial polygon from the second file. The points from this file should be used to construct a single Doubly Connected Edge List representing the inside of this polygon, with the first edge in this Doubly Connected Edge List stored in a dynamic array.
- Split the polygon into additional faces based on a listing of pairs of edges, creating a new edge between the middle of the first edge in the pair and the middle of the second edge in the pair. This numbering should be consistent with the numbering explained in the [Numbering](#markdown-header-numbering) section. The split will create exactly one new face. - Split the polygon into additional faces based on a listing of pairs of edges, creating a new edge between the middle of the first edge in the pair and the middle of the second edge in the pair. This numbering should be consistent with the numbering explained in the [Numbering](#numbering) section. The split will create exactly one new face.
- Output a summary of the watchtowers which lie in each face, consistent with the format explained under the [Format](#markdown-header-format) section. - Output a summary of the watchtowers which lie in each face, consistent with the format explained under the [Format](#format) section.
##### Doubly Connected Edge List ### Doubly Connected Edge List
In a doubly connected edge list, each edge is represented by two "half-edges". For the purposes of this assignment each half-edge should have: In a doubly connected edge list, each edge is represented by two "half-edges". For the purposes of this assignment each half-edge should have:
@ -232,9 +232,9 @@ This choice of organisation is not always strict (e.g. a vertex might be stored
We now revisit our earlier example of splitting a simple square face constructed with the points $\{(0, 0), (0, 2), (2, 2), (2, 0)\}$ which created four edges: We now revisit our earlier example of splitting a simple square face constructed with the points $\{(0, 0), (0, 2), (2, 2), (2, 0)\}$ which created four edges:
$$ ```math
\{(0, 0) \rightarrow (0, 2), (0, 2) \rightarrow (2, 2), (2, 2) \rightarrow (2, 0), (2, 0) \rightarrow (0, 0)\} \{(0, 0) \rightarrow (0, 2), (0, 2) \rightarrow (2, 2), (2, 2) \rightarrow (2, 0), (2, 0) \rightarrow (0, 0)\}
$$ ```
![](./images/image04.png) ![](./images/image04.png)
@ -266,9 +266,9 @@ You may assume in this task that splits never need to cross one another (e.g. a
One additional complexity exists in performing a split. This is where the two edges are not adjacent. Consider this example given as six points: One additional complexity exists in performing a split. This is where the two edges are not adjacent. Consider this example given as six points:
$$ ```math
\{(0, 0), (0, 2), (2, 2), (2, 0.5), (2, 0), (1.5, 0)\} \{(0, 0), (0, 2), (2, 2), (2, 0.5), (2, 0), (1.5, 0)\}
$$ ```
![](./images/image15.png) ![](./images/image15.png)
@ -457,23 +457,23 @@ There are two cases for half-plane checking which you might have to look at:
$m = \frac{y_2 - y_1}{x_2 - x_1}$, $c = y_2 - mx_2$ $m = \frac{y_2 - y_1}{x_2 - x_1}$, $c = y_2 - mx_2$
- We then use this gradient and intercept to see what we'd expect the point's $y$-coordinate to be if it lay on the line between $v_1$ and $v_2$ - We then use this gradient and intercept to see what we'd expect the point's $y$ coordinate to be if it lay on the line between $v_1$ and $v_2$
$y_{predicted} = mx + c$ $y_{predicted} = mx + c$
- We then use this value to see where the $y$-coordinate is in relation to this value - We then use this value to see where the $y$ coordinate is in relation to this value
$y_r = y - y_{predicted}$ $y_r = y - y_{predicted}$
- If $yr  0$, the point is inside the shape. - If $yr  0$, the point is inside the shape.
Note that the above only applies when the points forming the half-edge are ordered by increasing $x$-coordinate (or increasing $y$-coordinate in the case of equal $x$-coordinates). When the order is $x$-coordinate is decreasing (or $x$-coordinate is equal and $y$-coordinate is decreasing), we look for the opposite relations. Note that the above only applies when the points forming the half-edge are ordered by increasing $x$ coordinate (or increasing $y$ coordinate in the case of equal $x$ coordinates). When the order is $x$ coordinate is decreasing (or $x$ coordinate is equal and $y$ coordinate is decreasing), we look for the opposite relations.
![](./images/image09.png) ![](./images/image09.png)
- When $x_1 = x_2$ and $y_1  y_2$, the point is in the shape if $x ≤ x_1$. - When $x_1 = x_2$ and $y_1  y_2$, the point is in the shape if $x ≤ x_1$.
- Otherwise, if $x_1  x_2$ and $yr  0$, the point is in the shape. - Otherwise, if $x_1 ≥ x_2$ and $yr  0$, the point is in the shape.
### Updating changing faces ### Updating changing faces