more self-crossing and documentation
This commit is contained in:
parent
79d72839fe
commit
d6e177f9ea
45
IV/notes.txt
45
IV/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).
|
||||
|
||||
Gentle inflection at the end of the bend: the article does not specify how many
|
||||
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.
|
||||
Gentle inflection at the end of the bend
|
||||
----------------------------------------
|
||||
|
||||
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:
|
||||
The article does not specify how many 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 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
|
||||
intersects with AB. Some intersections may be missed (see the last example),
|
||||
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 ('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 ('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
|
||||
|
27
IV/wm.sql
27
IV/wm.sql
@ -191,28 +191,29 @@ begin
|
||||
p2 = p1;
|
||||
p1 = p0;
|
||||
continue when p3 is null;
|
||||
|
||||
angle = angle + abs(pi - st_angle(p1, p2, p3));
|
||||
end loop;
|
||||
|
||||
continue when abs(angle) <= pi;
|
||||
|
||||
-- sum of inflection angles for this bend is >180, so it may be self-crossing.
|
||||
-- now try to find another bend in this line that crosses this one.
|
||||
-- sum of inflection angles for this bend is >180, so it may be
|
||||
-- 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);
|
||||
p1 = 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
|
||||
-- sides of the plane, separated by endpoints p0 and p1.
|
||||
-- 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
|
||||
-- and end start at different sides of the plane, separated by endpoints
|
||||
-- p0 and p1.
|
||||
for j in 1..array_length(bends, 1) loop
|
||||
continue when i = j;
|
||||
|
||||
p2 = st_pointn(bends[j], 1);
|
||||
p3 = st_pointn(bends[j], -1);
|
||||
|
||||
-- are p2 and p3 on the same side of (p0,p1)? vector multiplication
|
||||
-- https://stackoverflow.com/questions/1560492/
|
||||
-- are p2 and p3 on the different sides of line(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);
|
||||
@ -222,16 +223,16 @@ begin
|
||||
multi = st_split(bends[j], this);
|
||||
continue when st_numgeometries(multi) = 1;
|
||||
|
||||
-- self-crossing detected!
|
||||
-- real self-crossing detected! Remove it.
|
||||
-- if j < i:
|
||||
-- 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])
|
||||
-- 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]
|
||||
-- bends[i] = bends[i][1]
|
||||
-- bends[i] = append(bends[i], multi[2][2..n])
|
||||
-- remove bends from bends[i+1] to bends[j] inclusive.
|
||||
|
||||
end loop;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user