explain self-crossing:

This commit is contained in:
Motiejus Jakštys 2021-05-19 22:57:47 +03:00 committed by Motiejus Jakštys
parent 95756033a2
commit 7073c15b88
2 changed files with 35 additions and 11 deletions

View File

@ -20,6 +20,7 @@
\usepackage{float} \usepackage{float}
\usepackage{tikz} \usepackage{tikz}
\usepackage{minted} \usepackage{minted}
\usepackage{fancyvrb}
\input{version.inc} \input{version.inc}
\input{vars.inc} \input{vars.inc}
@ -229,6 +230,8 @@ This section defines vocabulary and terms as defined in the rest of the paper.
\item[Baseline] is a line between bend's first and last vertex. \item[Baseline] is a line between bend's first and last vertex.
\item[Sum of inner angles] TBD.
\end{description} \end{description}
\subsection{Radians and Degrees} \subsection{Radians and Degrees}
@ -421,12 +424,36 @@ following the rules of the article.
\hfill \hfill
\begin{subfigure}[b]{.4\textwidth} \begin{subfigure}[b]{.4\textwidth}
\includegraphics[width=\textwidth]{fig6-self-crossing-after} \includegraphics[width=\textwidth]{fig6-self-crossing-after}
\caption{Bend's baseline is crossing another bend} \caption{Self-crossing removed}
\end{subfigure} \end{subfigure}
\caption{Originally Figure 6: self-line crossing} \caption{Originally Figure 6: self-line crossing}
\label{fig:fig6-self-crossing} \label{fig:fig6-self-crossing}
\end{figure} \end{figure}
The self-line-crossing may happen not by the neighboring bend, but by any other
bend in the line. For example, the baseline of bend A<->B may cross different
bends in between, as depicted in figure~\onpage{fig:ascii-selfcross}.
\begin{figure}[h]
\centering
\begin{BVerbatim}
\ \
B\ | _ __
| | / \ / \
| |___/ \___/A |
\_________________|
\end{BVerbatim}
\caption{A baseline crossing non-neighboring in-between bends}
\label{fig:ascii-selfcross}
\end{figure}
Naively implemented, checking every bend with every bend is costs $O(n^2)$.
It is possible to optimize this step and skip checking some of the bends. Only
bends whose sum of inner angles is $\pi$ can ever self-cross. If the value is
less than $\pi$, it cannot cross other bends. That way, only a fraction of
bends need to be checked.
\subsection{Attributes of a Single Bend} \subsection{Attributes of a Single Bend}
\subsection{Shape of a Bend} \subsection{Shape of a Bend}

17
wm.sql
View File

@ -99,7 +99,7 @@ $$ language plpgsql;
-- --
-- The text does not specify how many vertices can be "adjusted"; it can -- The text does not specify how many vertices can be "adjusted"; it can
-- equally be one or many. This function is adjusting many, as long as the -- equally be one or many. This function is adjusting many, as long as the
-- commulative inflection angle small (see variable below). -- cumulative inflection angle small (see variable below).
-- --
-- The implementation could be significantly optimized to avoid `st_reverse` -- The implementation could be significantly optimized to avoid `st_reverse`
-- and array reversals, trading for complexity in fix_gentle_inflections1. -- and array reversals, trading for complexity in fix_gentle_inflections1.
@ -235,9 +235,7 @@ begin
-- crosses an imaginary line of end-vertices -- crosses an imaginary line of end-vertices
-- go through each bend in the given line, and see if has a potential to -- go through each bend in the given line, and see if has a potential to
-- cross bends[i]. optimization: we care only about bends which beginning -- cross bends[i].
-- and end start at different sides of the plane, separated by endpoints
-- of the vertex.
j = 0; j = 0;
while j < array_length(bends, 1) loop while j < array_length(bends, 1) loop
j = j + 1; j = j + 1;
@ -251,17 +249,16 @@ begin
continue when st_numgeometries(multi) = 2 and continue when st_numgeometries(multi) = 2 and
(st_contains(bends[j], a) or st_contains(bends[j], b)); (st_contains(bends[j], a) or st_contains(bends[j], b));
-- stars are aligned, we are changing the bend -- vertices, segments and stars are aligned, we are changing the bend
mutated = true; mutated = true;
-- Sincere apologies to someone who will need to debug the block below. -- To understand the block below, I suggest you take a pencil and paper,
-- To understand it, I suggest you take a pencil and paper, draw a -- draw a self-crossing bend (fig6 from the article works well), and
-- self-crossing bend (fig6 from the article works well), and figure out -- figure out what happens here, by hand.
-- what happens here, by hand.
prev_length = array_length(bends, 1); prev_length = array_length(bends, 1);
if j < i then if j < i then
-- remove first vertex of the following bend, because the last -- remove first vertex of the following bend, because the last
-- segment is always duplicated with the i-th bend. -- segment is always duplicated with the i'th bend.
bends[i+1] = st_removepoint(bends[i+1], 0); bends[i+1] = st_removepoint(bends[i+1], 0);
bends[j] = st_geometryn(multi, 1); bends[j] = st_geometryn(multi, 1);
bends[j] = st_setpoint( bends[j] = st_setpoint(