beginnings of self-crossing
This commit is contained in:
parent
ec4b84b36f
commit
5e47e90370
13
notes.txt
13
notes.txt
@ -27,13 +27,12 @@ after a few bends have been skipped. E.g. ends of A<->B cross the line, but
|
||||
|
||||
|
||||
|
||||
If a bend with 180+ deg inflection is found, its line between inflection angles
|
||||
(AB in our examples) must be crossed with all the other bends to detect a
|
||||
possible line-crossing. This is O(N*M), where N is the total number of line
|
||||
segments, and M is the number of qualifying bends. In other words, can be very
|
||||
computationally expensive.
|
||||
If a bend with 180+ deg sum of inflection angles is found, its line between
|
||||
inflection angles (AB in our examples) must be crossed with all the other bends
|
||||
to detect a possible line-crossing. This is O(N*M), where N is the total number
|
||||
of line segments, and M is the number of qualifying bends. It is expensive.
|
||||
|
||||
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 example), but
|
||||
they will be eliminated by just joining A and B.
|
||||
intersects with AB. Some intersections may be missed (see the last example),
|
||||
but they will be eliminated by joining A and B anyway.
|
||||
|
@ -47,7 +47,7 @@ drop table if exists inflections, demo_inflections;
|
||||
create table inflections (name text, ways geometry[]);
|
||||
insert into inflections select name, fix_gentle_inflections(ways) from bends;
|
||||
create table demo_inflections (name text, i bigint, way geometry);
|
||||
insert into demo_inflections select a.name, generate_subscripts(a.ways, 1), unnest(a.ways) from inflections a;
|
||||
insert into demo_inflections select name, generate_subscripts(ways, 1), unnest(ways) from inflections;
|
||||
|
||||
do $$
|
||||
declare
|
||||
@ -67,3 +67,10 @@ begin
|
||||
perform assert_equals('LINESTRING(114 20,133 20,145 15,145 0,136 5,123 7,114 7)', st_astext(vinflections[2]));
|
||||
perform assert_equals('LINESTRING(123 7,114 7,111 2)', st_astext(vinflections[3]));
|
||||
end $$ language plpgsql;
|
||||
|
||||
-- SELF-LINE CROSSING
|
||||
drop table if exists selfcrossing, demo_selfcrossing;
|
||||
create table selfcrossing (name text, ways geometry[]);
|
||||
insert into selfcrossing select name, self_crossing(ways) from inflections;
|
||||
create table demo_selfcrossing (name text, i bigint, way geometry);
|
||||
insert into demo_selfcrossing select name, generate_subscripts(ways, 1), unnest(ways) from selfcrossing;
|
||||
|
26
wm.sql
26
wm.sql
@ -170,9 +170,35 @@ $$ language plpgsql;
|
||||
create or replace function self_crossing(INOUT bends geometry[]) as $$
|
||||
declare
|
||||
pi real;
|
||||
angle real;
|
||||
p geometry;
|
||||
p1 geometry;
|
||||
p2 geometry;
|
||||
p3 geometry;
|
||||
bend geometry;
|
||||
begin
|
||||
pi = radians(180);
|
||||
|
||||
-- go through the bends and find one where sum of inflection angle is >180
|
||||
foreach bend in array bends loop
|
||||
angle = 0;
|
||||
p3 = null;
|
||||
p2 = null;
|
||||
p1 = null;
|
||||
for p in (select geom from st_dumppoints(bend) order by path[1] asc) loop
|
||||
p3 = p2;
|
||||
p2 = p1;
|
||||
p1 = p;
|
||||
if p3 is null then
|
||||
continue;
|
||||
end if;
|
||||
angle = angle + abs(pi - st_angle(p1, p2, p3));
|
||||
end loop;
|
||||
|
||||
if abs(angle) > pi then
|
||||
raise notice 'maybe self-crossing bend %: %', st_astext(bend), round(degrees(abs(angle)));
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
end
|
||||
$$ language plpgsql;
|
||||
|
Loading…
Reference in New Issue
Block a user