Skip to content

Commit f85d754

Browse files
committed
docs: add VW explainer
1 parent 4bad576 commit f85d754

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

docs/algorithms/index.md

Whitespace-only changes.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: Visvalingam-Whyatt
3+
---
4+
5+
The Visvalingam-Whyatt reduction method provided by PolyShell consists of a few modifications to the original line
6+
reduction algorithm by Visvalingam and Whyatt[^1] in order to guarantee PolyShell's contract.
7+
8+
[^1]: [M. Visvalingam, J. D. Whyatt, 2013. Line generalisation by repeated elimination of points.](https://doi.org/10.1179/000870493786962263)
9+
10+
## Visvalingam-Whyatt Algorithm
11+
12+
In the original algorithm, vertices are assigned scores as measures of a point's importance, based upon the triangle formed by a vertex with its
13+
two neighbours. In the original algorithm this score is taken to be area displacement (AD), defined as the unsigned area
14+
of the associated triangle. Modifications to Visvalingam's algorithm by other scoring metrics have also been
15+
investigated[^2], leading to Visvalingam coining the term "effective area" (EA) to describe the score of a vertex more
16+
generally. Such examples include the introduction of the factor $EA = AD (1 - \cos{\theta})$ used by
17+
[Mapshaper](https://github.com/mbloch/mapshaper) to provide additional smoothing[^3]. The algorithm then proceeds by
18+
removing vertices in order of their score, from lowest to highest, until the score of a vertex exceeds some threshold.
19+
20+
[^2]: [M. Visvalingam, 2016. The Visvalingam Algorithm: Metrics, Measures and Heuristics.](https://doi.org/10.1080/00087041.2016.1151097)
21+
22+
[^3]: [M. Bloch, 2014. Some weighting functions for Visvalingam simplification.](https://gist.github.com/mbloch/5505b92642f6e0361037)
23+
24+
---
25+
26+
## Modifications
27+
28+
To apply the Visvalingam-Whyatt algorithm to the problem of polygon reduction, it is necessary to correct for possible
29+
self-intersections which may occur. These issues tend to occur most frequently in channel-like geometries, like the
30+
example given below. One fairly common solution is to check that removal of a vertex will not lead to a
31+
self-intersection, otherwise it is skipped. Naive implementations can prove costly, however this can be somewhat
32+
improved by first querying an R-tree to reduce the number of likely culprits.
33+
34+
TODO: Img with caption explanation
35+
36+
Once the algorithm has been extended to the reduction of polygons, ensuring coverage is a relatively simple process.
37+
When assigning scores, if removal of a vertex would lead to a loss in coverage, the effective area is said to be
38+
infinite, otherwise it is set according to any valid metric. Thus, at each iteration, vertices removed are guaranteed
39+
to increase the area of the reduced polygon and hence ensure coverage at each step.
40+
41+
---
42+
43+
## Implementation Notes
44+
45+
The formulation of PolyShell's contract provides the opportunity for some additional performance improvements beyond
46+
those possible when using the standard Visvalingam-Whyatt algorithm. In this section we will describe all the
47+
adjustments made beyond a typical implementation of the Visvalingam-Whyatt algorithm. We will also provide some
48+
justification as to why these reductions are valid and some expectations on the resulting uplift in performance.
49+
50+
### Pre-processing
51+
52+
Immediately obvious is that the minimal reduction of any polygon is it's convex hull. For most purposes this is a poor
53+
reduction, losing almost all detail in the original shape. The convex hull does however identify which vertices are
54+
invariant under reduction. This feature allows us to segment the polygon into isolated sections, each of which can be
55+
reduced independently of the others, allowing for parallel reduction on a single polygon. For this purpose we use
56+
Melkman's algorithm, to compute the convex hull in linear time[^4].
57+
58+
[^4]: [A. Melkman, 1987. On-line construction of the convex hull of a simple polyline.](https://doi.org/10.1016/0020-0190(87)90086-X)
59+
60+
### R-tree Adjustments
61+
62+
Adaptations of Visvalingam-Whyatt for polygon reduction require use of an R-tree to prevent self-intersections. For
63+
typical reduction algorithms, this requires edges to be removed from the tree and new edges inserted at each iteration.
64+
In PolyShell's implementation, both of these steps are skipped while retaining correctness. Deletion is no longer
65+
necessary, as our reduction only expands outwards. Hence, edges which are removed can never cause self-intersections.
66+
Similarly, no new edges need to be added, as if a reduction causes an intersection with a new edge, then it would have
67+
already caused an intersection with one of the original edges. We have found that while a larger tree must be queried
68+
at every iteration, the savings by not rebalancing the tree outweigh any potential cost.

mkdocs.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ theme:
55

66
features:
77
- navigation.path
8+
- navigation.footer
89
- navigation.instant
910
- navigation.instant.prefetch
1011
- navigation.instant.progress
@@ -41,6 +42,8 @@ theme:
4142
name: Switch to system preference
4243

4344
markdown_extensions:
45+
- pymdownx.arithmatex:
46+
generic: true
4447
- pymdownx.highlight:
4548
anchor_linenums: true
4649
line_spans: __span
@@ -65,6 +68,13 @@ markdown_extensions:
6568

6669
plugins:
6770
- search
71+
extra_javascript:
72+
- javascripts/katex.js
73+
- https://unpkg.com/katex@0/dist/katex.min.js
74+
- https://unpkg.com/katex@0/dist/contrib/auto-render.min.js
75+
76+
extra_css:
77+
- https://unpkg.com/katex@0/dist/katex.min.css
6878

6979
repo_url: https://github.com/ECMWFCode4Earth/PolyShell
7080
repo_name: polyshell

0 commit comments

Comments
 (0)