wip self-crossing

This commit is contained in:
Motiejus Jakštys 2021-03-04 17:59:26 +02:00
parent 72f89360f7
commit 79d72839fe
3 changed files with 22 additions and 7 deletions

View File

@ -12,13 +12,13 @@ after a few bends have been skipped. E.g. ends of A<->B cross the line, but
,______ ,______
/ \ / \
|___A | \ | |___A | \ \
\ | B\ | __ \ | B\ | __
\ | | | / \ \ | | | / \
/ | | |___,---,___/A | / | | |___,---,___/A |
/ | \_________________| / | \_________________|
\ | \ |
\ | \ | \ | \ \
/ / B\ | _ __ / / B\ | _ __
----/ / | | / \ / \ ----/ / | | / \ / \
/ ,____/ | |___/ \___/A | / ,____/ | |___/ \___/A |

View File

@ -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 ('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 ('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',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)')); 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 -- DETECT BENDS

View File

@ -175,6 +175,8 @@ declare
s2 real; s2 real;
s3 real; s3 real;
bend geometry; bend geometry;
this geometry;
multi geometry;
begin begin
pi = radians(180); pi = radians(180);
@ -199,7 +201,6 @@ begin
-- now try to find another bend in this line that crosses this one. -- now try to find another bend in this line that crosses this one.
p0 = st_pointn(bends[i], 1); p0 = st_pointn(bends[i], 1);
p1 = 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]. -- 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 -- optimization: we care only about bends which beginning and end start at different
@ -210,14 +211,27 @@ begin
p2 = st_pointn(bends[j], 1); p2 = st_pointn(bends[j], 1);
p3 = 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))); 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))); 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); continue when sign(s2) = sign(s3);
-- bend j may be crossing bend i, and it has a chance to be "important" -- -- do end vertices of bend[i] cross bend[j]?
-- p2 and p3 are in different sides of the plane as delimited by p0 and p1. this = st_makeline(st_pointn(bends[i], 1), st_pointn(bends[i], -1));
-- now does it really cross the line (p0, p1)? 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; end loop;