more self-crossing and documentation
This commit is contained in:
parent
d66d1ac248
commit
87849132d1
45
notes.txt
45
notes.txt
@ -1,14 +1,22 @@
|
|||||||
Definition of a bend: ends of the line should always be bends, otherwise not
|
Definition of a bend
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Ends of the line should always be bends, otherwise not
|
||||||
all line vertices are covered by bends (definition elsewhere).
|
all line vertices are covered by bends (definition elsewhere).
|
||||||
|
|
||||||
Gentle inflection at the end of the bend: the article does not specify how many
|
Gentle inflection at the end of the bend
|
||||||
vertices should be included when calculating the end-of-bend inflection. We
|
----------------------------------------
|
||||||
chose the iterative approach -- as long as the angle is "right" and the
|
|
||||||
distance is (greedily) decreasing, keep going.
|
|
||||||
|
|
||||||
Self-line crossing when cutting a bend: the self-line-crossing may happen
|
The article does not specify how many vertices should be included when
|
||||||
after a few bends have been skipped. E.g. ends of A<->B cross the line, but
|
calculating the end-of-bend inflection. We chose the iterative approach -- as
|
||||||
"swallow" a few more in between:
|
long as the angle is "right" and the distance is (greedily) decreasing, keep
|
||||||
|
going.
|
||||||
|
|
||||||
|
Self-line crossing when cutting a bend
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
The self-line-crossing may happen after a few bends have been skipped. E.g.
|
||||||
|
ends of A<->B cross the line, but "swallow" a few more in between:
|
||||||
|
|
||||||
,______
|
,______
|
||||||
/ \
|
/ \
|
||||||
@ -36,3 +44,24 @@ This may be simplified: if other bend's endpoints (A' and B') are in the same
|
|||||||
sub-plane as divided by AB, then the bend can be skipped from checking if it
|
sub-plane as divided by AB, then the bend can be skipped from checking if it
|
||||||
intersects with AB. Some intersections may be missed (see the last example),
|
intersects with AB. Some intersections may be missed (see the last example),
|
||||||
but they will be eliminated by joining A and B anyway.
|
but they will be eliminated by joining A and B anyway.
|
||||||
|
|
||||||
|
Also, there is another way to remove self-crossing, without removing most of
|
||||||
|
the bend. E.g. from:
|
||||||
|
|
||||||
|
|
||||||
|
\ \
|
||||||
|
B\ | __
|
||||||
|
| | / \
|
||||||
|
| |____/A |
|
||||||
|
\__________|
|
||||||
|
|
||||||
|
To:
|
||||||
|
|
||||||
|
\ \_
|
||||||
|
B\ `-,_.__
|
||||||
|
| A' \
|
||||||
|
| |
|
||||||
|
\__________|
|
||||||
|
|
||||||
|
But perhaps it doesn't look quite as natural. I will trust the original
|
||||||
|
article to do the right thing here.
|
||||||
|
@ -18,7 +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 ('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
|
||||||
|
27
wm.sql
27
wm.sql
@ -191,28 +191,29 @@ begin
|
|||||||
p2 = p1;
|
p2 = p1;
|
||||||
p1 = p0;
|
p1 = p0;
|
||||||
continue when p3 is null;
|
continue when p3 is null;
|
||||||
|
|
||||||
angle = angle + abs(pi - st_angle(p1, p2, p3));
|
angle = angle + abs(pi - st_angle(p1, p2, p3));
|
||||||
end loop;
|
end loop;
|
||||||
|
|
||||||
continue when abs(angle) <= pi;
|
continue when abs(angle) <= pi;
|
||||||
|
|
||||||
-- sum of inflection angles for this bend is >180, so it may be self-crossing.
|
-- sum of inflection angles for this bend is >180, so it may be
|
||||||
-- now try to find another bend in this line that crosses this one.
|
-- self-crossing. now try to find another bend in this line that
|
||||||
|
-- crosses an imaginary line of end-vertices
|
||||||
p0 = st_pointn(bends[i], 1);
|
p0 = st_pointn(bends[i], 1);
|
||||||
p1 = st_pointn(bends[i], -1);
|
p1 = 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 the given line, and see if has a potential to
|
||||||
-- optimization: we care only about bends which beginning and end start at different
|
-- cross bends[i]. optimization: we care only about bends which beginning
|
||||||
-- sides of the plane, separated by endpoints p0 and p1.
|
-- and end start at different sides of the plane, separated by endpoints
|
||||||
|
-- p0 and p1.
|
||||||
for j in 1..array_length(bends, 1) loop
|
for j in 1..array_length(bends, 1) loop
|
||||||
continue when i = j;
|
continue when i = j;
|
||||||
|
|
||||||
p2 = st_pointn(bends[j], 1);
|
p2 = st_pointn(bends[j], 1);
|
||||||
p3 = st_pointn(bends[j], -1);
|
p3 = st_pointn(bends[j], -1);
|
||||||
|
|
||||||
-- are p2 and p3 on the same side of (p0,p1)? vector multiplication
|
-- are p2 and p3 on the different sides of line(p0,p1)? vector
|
||||||
-- https://stackoverflow.com/questions/1560492/
|
-- 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);
|
||||||
@ -222,16 +223,16 @@ begin
|
|||||||
multi = st_split(bends[j], this);
|
multi = st_split(bends[j], this);
|
||||||
continue when st_numgeometries(multi) = 1;
|
continue when st_numgeometries(multi) = 1;
|
||||||
|
|
||||||
-- self-crossing detected!
|
-- real self-crossing detected! Remove it.
|
||||||
-- if j < i:
|
-- if j < i:
|
||||||
-- bends[j] = multi[1][1...n-1]; that will have all the vertices of bends[j],
|
-- bends[j] = multi[1][1...n-1]; that will have all the vertices of bends[j],
|
||||||
-- except the crossing itself.
|
-- except the crossing and what comes after it.
|
||||||
-- bends[j] = append(bends[j], bends[i][-1])
|
-- bends[j] = append(bends[j], bends[i][-1])
|
||||||
-- remove bends from bends[j+1] to bends[i] inclusive.
|
-- remove bends from bends[j+1] to bends[i] inclusive.
|
||||||
-- elif j > i:
|
-- elif j > i:
|
||||||
-- remove bends from bends[i+1] to bends[j-1] inclusive.
|
-- bends[i] = bends[i][1]
|
||||||
-- bends[j] = multi[2][2..n]
|
-- bends[i] = append(bends[i], multi[2][2..n])
|
||||||
-- bends[i]
|
-- remove bends from bends[i+1] to bends[j] inclusive.
|
||||||
|
|
||||||
end loop;
|
end loop;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user