self-crossing bugfix
This commit is contained in:
parent
9f717f1e3a
commit
d390d373a9
14
notes.txt
14
notes.txt
@ -52,6 +52,20 @@ To:
|
||||
But perhaps it doesn't look quite as natural. I will trust the original
|
||||
article to do the right thing here and remove the bend altogether.
|
||||
|
||||
ALSO: the bends should be iterated from different directions:
|
||||
|
||||
for i := 0; i < len(bends); i++ {
|
||||
for j := 0; j < i; j++ {
|
||||
...
|
||||
}
|
||||
for j := len(bends); j > i; j-- {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
So if there are multiple bends between the baseline, they will be cut
|
||||
correctly.
|
||||
|
||||
The Context of a Bend
|
||||
---------------------
|
||||
|
||||
|
@ -53,7 +53,9 @@ insert into wm_figures (name, way) values ('inflection-1',ST_GeomFromText('LINES
|
||||
insert into wm_figures (name, way) values ('multi-island',ST_GeomFromText('MULTILINESTRING((-15 10,-10 10,-5 11,0 11,5 11,10 10,11 9,13 10,15 9),(-5 11,-2 15,0 16,2 15,5 11))'));
|
||||
|
||||
-- TODO: there is a bug and it does not go through `self_crossing` function.
|
||||
--insert into wm_figures (name, way) values ('selfcrossing-1',ST_GeomFromText('LINESTRING(-27 180,-20 166,-21 142,-18 136,55 136,55 136,71 145,44 165,37 146,22 145,14 164,11 164,3 146,-12 146,-13 176,-18 184)'));
|
||||
insert into wm_figures (name, way) values ('selfcrossing-1',ST_GeomFromText('LINESTRING(-27 180,-20 166,-21 142,-18 136,55 136,55 136,71 145,44 165,37 146,22 145,14 164,11 164,3 146,-12 146,-13 176,-18 184)'));
|
||||
insert into wm_figures (name, way) values ('selfcrossing-1-rev',ST_Reverse(ST_Translate((select way from wm_figures where name='selfcrossing-1'), 60, 0)));
|
||||
|
||||
|
||||
-- Run ST_SimplifyWM in debug mode, so `wm_debug` is populated. That table
|
||||
-- is used for geometric assertions later in the file.
|
||||
|
76
wm.sql
76
wm.sql
@ -236,12 +236,7 @@ begin
|
||||
|
||||
-- go through each bend in the given line, and see if has a potential to
|
||||
-- cross bends[i].
|
||||
j = 0;
|
||||
while j < array_length(bends, 1) loop
|
||||
j = j + 1;
|
||||
continue when i = j;
|
||||
|
||||
-- do end vertices of bend[i] cross bend[j]?
|
||||
for j in 1..i-1 loop
|
||||
a = st_pointn(bends[i], 1);
|
||||
b = st_pointn(bends[i], -1);
|
||||
multi = st_split(bends[j], st_makeline(a, b));
|
||||
@ -257,35 +252,46 @@ begin
|
||||
-- figure out what happens here, by hand. I know it's hard to follow.
|
||||
-- Apologies.
|
||||
prev_length = array_length(bends, 1);
|
||||
if j < i then
|
||||
-- remove first vertex of the following bend, because the last
|
||||
-- segment is always duplicated with the i'th bend.
|
||||
bends[i+1] = st_removepoint(bends[i+1], 0);
|
||||
bends[j] = st_geometryn(multi, 1);
|
||||
bends[j] = st_setpoint(
|
||||
bends[j],
|
||||
st_npoints(bends[j])-1,
|
||||
st_pointn(bends[i], st_npoints(bends[i]))
|
||||
);
|
||||
bends = bends[1:j] || bends[i+1:prev_length];
|
||||
j = i;
|
||||
else
|
||||
-- remove last vertex of the previous bend, because the last
|
||||
-- segment is duplicated with the i'th bend.
|
||||
bends[i-1] = st_removepoint(bends[i-1], st_npoints(bends[i-1])-1);
|
||||
-- continue debugging the selfcrossing-1 here.
|
||||
--raise notice 'previous bend: %', st_astext(bends[i-1]);
|
||||
--raise notice 'multi: %', st_astext(multi);
|
||||
--raise notice '2: removing first point from %', st_astext(st_geometryn(multi, st_numgeometries(multi)));
|
||||
--mutated = false;
|
||||
--return;
|
||||
bends[i] = st_makeline(
|
||||
st_pointn(bends[i], 1),
|
||||
st_removepoint(st_geometryn(multi, st_numgeometries(multi)), 0)
|
||||
);
|
||||
bends = bends[1:i] || bends[j+1:prev_length];
|
||||
end if;
|
||||
j = j - prev_length + array_length(bends, 1);
|
||||
|
||||
-- remove first vertex of the following bend, because the last
|
||||
-- segment is always duplicated with the i'th bend.
|
||||
bends[i+1] = st_removepoint(bends[i+1], 0);
|
||||
bends[j] = st_geometryn(multi, 1);
|
||||
bends[j] = st_setpoint(
|
||||
bends[j],
|
||||
st_npoints(bends[j])-1,
|
||||
st_pointn(bends[i], st_npoints(bends[i]))
|
||||
);
|
||||
bends = bends[1:j] || bends[i+1:prev_length];
|
||||
exit;
|
||||
end loop;
|
||||
|
||||
for j in reverse array_length(bends, 1)..i+1 loop
|
||||
a = st_pointn(bends[i], 1);
|
||||
b = st_pointn(bends[i], -1);
|
||||
multi = st_split(bends[j], st_makeline(a, b));
|
||||
continue when st_numgeometries(multi) = 1;
|
||||
continue when st_numgeometries(multi) = 2 and
|
||||
(st_contains(bends[j], a) or st_contains(bends[j], b));
|
||||
|
||||
-- vertices, segments and stars are aligned, we are changing the bend
|
||||
mutated = true;
|
||||
|
||||
-- To understand the block below, I suggest you take a pencil and paper,
|
||||
-- draw a self-crossing bend (fig6 from the article works well), and
|
||||
-- figure out what happens here, by hand. I know it's hard to follow.
|
||||
-- Apologies.
|
||||
prev_length = array_length(bends, 1);
|
||||
-- remove last vertex of the previous bend, because the last
|
||||
-- segment is duplicated with the i'th bend.
|
||||
bends[i-1] = st_removepoint(bends[i-1], st_npoints(bends[i-1])-1);
|
||||
-- continue debugging the selfcrossing-1 here.
|
||||
bends[i] = st_makeline(
|
||||
st_pointn(bends[i], 1),
|
||||
st_removepoint(st_geometryn(multi, st_numgeometries(multi)), 0)
|
||||
);
|
||||
bends = bends[1:i] || bends[j+1:prev_length];
|
||||
exit;
|
||||
end loop;
|
||||
end loop;
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user