commit d66d1ac248fdeb9d0f21e6c55df4e7a2afa8d656 (tree)
parent 942cc4cc501ebe66d942d6f80a61ba8753eaeb8c
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date: Wed, 19 May 2021 22:57:45 +0300
wip self-crossing
Diffstat:
3 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/notes.txt b/notes.txt
@@ -12,13 +12,13 @@ after a few bends have been skipped. E.g. ends of A<->B cross the line, but
,______
/ \
- |___A | \ |
+ |___A | \ \
\ | B\ | __
\ | | | / \
/ | | |___,---,___/A |
/ | \_________________|
\ |
- \ | \ |
+ \ | \ \
/ / B\ | _ __
----/ / | | / \ / \
/ ,____/ | |___/ \___/A |
diff --git a/tests.sql b/tests.sql
@@ -18,6 +18,7 @@ insert into figures (name, way) values ('fig3',ST_GeomFromText('LINESTRING(0 0,1
insert into figures (name, way) values ('fig3-1',ST_GeomFromText('LINESTRING(0 0,12 0,13 4,20 2,20 0,32 0,33 10,38 16,43 15,44 10,44 0)'));
insert into figures (name, way) values ('fig5',ST_GeomFromText('LINESTRING(0 39,19 52,27 77,26 104,41 115,49 115,65 103,65 75,53 45,63 15,91 0)'));
insert into figures (name, way) values ('fig6',ST_GeomFromText('LINESTRING(84 47,91 59,114 64,122 80,116 92,110 93,106 106,117 118,136 107,135 76,120 45,125 39,141 39,147 32)'));
+insert into figures (name, way) values ('fig6-rev',st_reverse(st_translate((select way from figures where name='fig6'), 80, 0)));
insert into figures (name, way) values ('inflection-1',ST_GeomFromText('LINESTRING(110 24,114 20,133 20,145 15,145 0,136 5,123 7,114 7,111 2)'));
-- DETECT BENDS
diff --git a/wm.sql b/wm.sql
@@ -175,6 +175,8 @@ declare
s2 real;
s3 real;
bend geometry;
+ this geometry;
+ multi geometry;
begin
pi = radians(180);
@@ -199,7 +201,6 @@ begin
-- now try to find another bend in this line that crosses this one.
p0 = st_pointn(bends[i], 1);
p1 = st_pointn(bends[i], -1);
- --this = st_makeline(st_pointn(bends[i], 1), st_pointn(bends[i], -1));
-- go through each bend in this line, and see if has a potential to cross bends[i].
-- optimization: we care only about bends which beginning and end start at different
@@ -210,14 +211,27 @@ begin
p2 = st_pointn(bends[j], 1);
p3 = st_pointn(bends[j], -1);
- -- https://stackoverflow.com/questions/1560492
+ -- are p2 and p3 on the same side of (p0,p1)? vector multiplication
+ -- https://stackoverflow.com/questions/1560492/
s2 = (st_x(p0)-st_x(p1)*(st_y(p2)-st_y(p1))-(st_y(p0)-st_y(p1))*(st_x(p2)-st_x(p1)));
s3 = (st_x(p0)-st_x(p1)*(st_y(p3)-st_y(p1))-(st_y(p0)-st_y(p1))*(st_x(p3)-st_x(p1)));
continue when sign(s2) = sign(s3);
- -- bend j may be crossing bend i, and it has a chance to be "important" --
- -- p2 and p3 are in different sides of the plane as delimited by p0 and p1.
- -- now does it really cross the line (p0, p1)?
+ -- do end vertices of bend[i] cross bend[j]?
+ this = st_makeline(st_pointn(bends[i], 1), st_pointn(bends[i], -1));
+ multi = st_split(bends[j], this);
+ continue when st_numgeometries(multi) = 1;
+
+ -- self-crossing detected!
+ -- if j < i:
+ -- bends[j] = multi[1][1...n-1]; that will have all the vertices of bends[j],
+ -- except the crossing itself.
+ -- bends[j] = append(bends[j], bends[i][-1])
+ -- remove bends from bends[j+1] to bends[i] inclusive.
+ -- elif j > i:
+ -- remove bends from bends[i+1] to bends[j-1] inclusive.
+ -- bends[j] = multi[2][2..n]
+ -- bends[i]
end loop;