move section of self_crossing to a separate function
This commit is contained in:
parent
fd1250a73b
commit
5491f574e6
65
wm.sql
65
wm.sql
@ -209,6 +209,34 @@ begin
|
||||
end
|
||||
$$ language plpgsql;
|
||||
|
||||
drop function if exists if_selfcross;
|
||||
create function if_selfcross(
|
||||
bendi geometry,
|
||||
bendj geometry
|
||||
) returns geometry as $$
|
||||
declare
|
||||
a geometry;
|
||||
b geometry;
|
||||
partitions geometry;
|
||||
begin
|
||||
a = st_pointn(bendi, 1);
|
||||
b = st_pointn(bendi, -1);
|
||||
partitions = st_split(bendj, st_makeline(a, b));
|
||||
|
||||
if st_numgeometries(partitions) = 1 then
|
||||
return null;
|
||||
end if;
|
||||
|
||||
if st_numgeometries(partitions) = 2 and
|
||||
(st_contains(bendj, a) or st_contains(bendj, b)) then
|
||||
return null;
|
||||
end if;
|
||||
|
||||
return partitions;
|
||||
end
|
||||
$$ language plpgsql;
|
||||
|
||||
|
||||
-- self_crossing eliminates self-crossing from the bends, following the
|
||||
-- article's section "Self-line Crossing When Cutting a Bend".
|
||||
drop function if exists self_crossing;
|
||||
@ -220,7 +248,6 @@ declare
|
||||
pi constant real default radians(180);
|
||||
i int4;
|
||||
j int4;
|
||||
prev_length int4;
|
||||
a geometry;
|
||||
b geometry;
|
||||
multi geometry;
|
||||
@ -234,25 +261,18 @@ begin
|
||||
-- self-crossing. now try to find another bend in this line that
|
||||
-- crosses an imaginary line of end-vertices
|
||||
|
||||
-- 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.
|
||||
|
||||
-- go through each bend in the given line, and see if has a potential to
|
||||
-- cross bends[i].
|
||||
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));
|
||||
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
|
||||
select if_selfcross(bends[i], bends[j]) into multi;
|
||||
continue when multi is null;
|
||||
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 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);
|
||||
@ -262,26 +282,19 @@ begin
|
||||
st_npoints(bends[j])-1,
|
||||
st_pointn(bends[i], st_npoints(bends[i]))
|
||||
);
|
||||
bends = bends[1:j] || bends[i+1:prev_length];
|
||||
bends = bends[1:j] || bends[i+1:];
|
||||
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
|
||||
select if_selfcross(bends[i], bends[j]) into multi;
|
||||
continue when multi is null;
|
||||
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);
|
||||
@ -290,7 +303,7 @@ begin
|
||||
st_pointn(bends[i], 1),
|
||||
st_removepoint(st_geometryn(multi, st_numgeometries(multi)), 0)
|
||||
);
|
||||
bends = bends[1:i] || bends[j+1:prev_length];
|
||||
bends = bends[1:i] || bends[j+1:];
|
||||
exit;
|
||||
end loop;
|
||||
end loop;
|
||||
|
Loading…
Reference in New Issue
Block a user