Чтобы создать список всех полигонов и их соседей, вы можете сделать что-то вроде этого:
neighbours[polygons_] := {#,
Flatten@Position[polygons,
a_List /; Length[Intersection[a, #]] == 2]} & /@ polygons;
Затем neighbours[polygons]
создает список, в котором i
-ая запись состоит из polygons[[i]]
и индексов соседей polygons[[i]]
.
Для второй части вашего вопроса, вы можете сделать что-то вроде
wake[polygons_] :=
Module[{edges, boundaries, wakelist, body},
edges[polylist_] := Flatten[Map[Partition[#, 2, 1, 1] &, polylist], 1];
boundaries = Cases[Tally[
edges[polygons], (Sort[#1] == Sort[#2]) &], {a_, b_} /; b == 1 :> a];
wakelist =
DeleteDuplicates[
Map[Cases[polygons, a_ /; (Length[Intersection[a, #]] == 2)][[1]] &,
boundaries]];
{#, Flatten@Position[polygons, a_List /; (Length[Intersection[#, a]] == 2 &&
Not[MemberQ[wakelist, a]])]} & /@ wakelist]
В wake
полигон считается панелью следа, если он содержит ребро, у которого нет соседних полигонов. Я не знаю, всегда ли это верно, но, похоже, это работает для примера в вопросе.
Редактировать
Чтобы разделить полный список полигонов по полигонам следа и тела, вы можете сделать что-то вроде
split[polygons_] := Module[{edges, boundaries, wakelist},
edges[polylist_] := Flatten[Map[Partition[#, 2, 1, 1] &, polygons], 1];
boundaries = Cases[Tally[edges[polygons],
(Sort[#1] == Sort[#2]) &], {a_, b_} /; b == 1 :> a];
wakelist = DeleteDuplicates[Map[Cases[polygons,
a_ /; (Length[Intersection[a, #]] == 2)][[1]] &, boundaries]];
{wakelist, Complement[polygons, wakelist]}];
Затем split[polygons]
создаст список из двух подсписков. Первый подсписок содержит все полигоны, принадлежащие следу, а второй - все полигоны, принадлежащие телу. Поскольку split
уже отделяет след от тела, мы можем переписать wake
в соответствии с
wake2[wakelist_, bodylist_] := {#, Flatten@Position[bodylist,
a_List /; (Length[Intersection[#, a]] == 2)]} & /@ wakelist
Затем, чтобы найти список многоугольников тела плюс индексы их соседей, и список многоугольников следа плюс индексы соседних многоугольников тела, которые вы можете сделать
{wakepols, bodypols} = split[polygons];
bodylist = neighbours[bodypols];
wakelist = wake[wakepols, bodypols];
Обратите внимание, что индексы полигонов в bodylist
и wakelist
теперь относятся к полигонам в bodypols
, а не к полному списку polygons
.