gentle inflection of a bend

This commit is contained in:
Motiejus Jakštys 2021-02-22 08:44:23 +02:00
parent f42354800b
commit 7bef5ba36a
2 changed files with 54 additions and 0 deletions

View File

@ -16,11 +16,13 @@ create table figures (name text, way geometry);
insert into figures (name, way) values ('fig3',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,60 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,91 0)'));
insert into figures (name, way) values ('inflection-1',ST_GeomFromText('LINESTRING(129 45,131 56,130 82,128 99,147 104,149 89,147 68,141 52)'));
drop table if exists bends;
create table bends (way geometry);
insert into bends select unnest(detect_bends((select way from figures where name='fig3')));
insert into bends select unnest(detect_bends((select way from figures where name='fig5')));
insert into bends select unnest(detect_bends((select way from figures where name='inflection-1')));
do $$
declare

View File

@ -70,7 +70,59 @@ $$ language plpgsql;
-- fix_gentle_inflections moves bend endpoints following "Gentle Inflection at
-- End of a Bend" section.
--
-- The text does not specify how many vertices can be "adjusted"; it can
-- equally be one or many. This function is adjusting many, as long as the
-- commulative inflection angle is less than pi/6 (30 deg).
create or replace function fix_gentle_inflections(INOUT bends geometry[]) as $$
declare
prev_bend geometry;
bend geometry;
p geometry;
p1 geometry;
p2 geometry;
p3 geometry;
begin
foreach bend in array bends loop
if prev_bend is null then
prev_bend = bend;
continue;
end if;
-- Predicate: two bends will always share an edge. Assuming (A,B,C,D,E,F)
-- is a bend:
-- C________D
-- / \
-- \________/ \_______/
-- A B E F
--
-- Then edges (A,B) and (E,F) are shared with the neighboring bends.
--
--
-- Assume this curve:
--
-- A______B
-- ---' `---.___. E
-- C D |
-- _I |
-- '---.________ |
-- H G'---+ F
--
-- After processing the curve following the definition of a bend, the bend
-- [A-G] would be detected. Assuming inflection point G and H are "small",
-- the bend would be extended by two edges to [A,I].
for p in (select geom from st_dumppoints(prev_bend) order by path[1] desc) loop
p3 = p2;
p2 = p1;
p1 = p;
if p3 is null then
continue;
end if;
-- (p2, p1) is shared with the current bend.
end loop;
prev_bend = bend;
end loop;
end
$$ language plpgsql;