Rectangular Compartments
Divide an irregular closed polygon into component Rectangles
1
def Rect(srf:var[]..[])
2
{
3
srf01 = List.Flatten(srf.Explode(),-1);
4
srf02 = List.FilterByBoolMask(srf01,List.Count(srf01.Vertices.PointGeometry<1>)>3)["in"];
5
crv00 = srf02.PerimeterCurves();
6
pcv01 = PolyCurve.ByJoinedCurves(crv00);
7
vtx01 = List.Flatten(srf02.Vertices.PointGeometry,-1);
8
9
//Offset Perimter Curves Outwards
10
seg01 = 100;
11
off01 = List.Flatten(crv00,-1)[0].Length/seg01;
12
pcv02 = pcv01<1>.Offset([off01,-off01]);
13
pcv03 = List.FirstItem(pcv02<1>);
14
pcv04 = List.LastItem(pcv02<1>);
15
pcv05 = pcv03.Length > pcv04.Length ? pcv03 : pcv04;
16
17
//Inward Vectors
18
acc01 = 8;
19
pnt01 = crv00<1><2>.PointAtParameter((0..1..#acc01));
20
vct00 = crv00<1><2>.NormalAtParameter((0..1..#acc01));
21
vct01 = List.GetItemAtIndex(vct00<1><2>,Math.Floor(acc01/2));
22
pnt02 = List.Flatten(pnt01.Project(pcv05,vct01)<1><2>,-1);
23
bln01 = List.AllTrue((pnt01.DistanceTo(pnt02)!=off01)<1><2>);
24
vct02 = bln01 ? vct01 : vct01.Reverse();
25
26
//Rectangle aligned to Surface Boundaries
27
pnt03 = List.Flatten(pnt01.Project(pcv05,vct02)<1><2>,-1);
28
dis01 = Math.Round(pnt01.DistanceTo(pnt03)-off01,6);
29
bln02 = List.DropItems(dis01<1><2>,-1)==List.DropItems(dis01<1><2>,1);
30
fil01 = List.IndexOf(bln02<1><2>,true);
31
fil02 = fil01==-1 ? acc01 : fil01;
32
fil03 = List.DropItems(bln02<1><2>,fil02<1><2>);
33
fil04 = List.IndexOf(fil03<1><2>,false);
34
fil05 = fil04 == -1 ? acc01-1 : fil04+1;
35
fil06 = List.DropItems(pnt01<1><2>,fil02<1><2>);
36
pnt04 = List.TakeItems(fil06<1><2>,fil05<1><2>);
37
fil07 = List.DropItems(pnt03<1><2>,fil02<1><2>);
38
pnt05 = List.TakeItems(fil07<1><2>,fil05<1><2>);
39
lin01 = List.Clean(Line.ByStartPointEndPoint(pnt04,pnt05).ExtendEnd(-off01),false);
40
bln03 = List.Count(List.RemoveIfNot(lin01.Intersect(pcv01)<1><2><3>,"Point")<1><2><3>)>2;
41
lin02 = List.FilterByBoolMask(lin01,bln03)["out"];
42
lin03 = List.FirstItem(lin02<1><2>);
43
lin04 = List.LastItem(lin02<1><2>);
44
vct03 = Vector.ByTwoPoints(lin03.PointAtParameter(0.5),lin04.PointAtParameter(0.5));
45
vct04 = Vector.ByTwoPoints(lin04.PointAtParameter(0.5),lin03.PointAtParameter(0.5));
46
47
//Shift edge towards Closest Vertex
48
pnt06 = List.Transpose(vtx01<3>.Project(lin03<1><2>,vct03<1><2>)<1>);
49
bln04 = DSCore.Object.IsNull(List.Count(pnt06<1><2><3>)>0)?true:List.Count(pnt06<1><2><3>)>0;
50
dis02 = lin03.DistanceTo(List.FilterByBoolMask(vtx01,bln04<1><2>)["in"]);
51
lin05 = lin03.Translate(vct04,List.MinimumItem(dis02));
52
pnt07 = List.Transpose(vtx01<3>.Project(lin04<2><1>,vct04<2><1>)<1>);
53
bln05 = DSCore.Object.IsNull(List.Count(pnt07<1><2><3>)>0)?true:List.Count(pnt07<1><2><3>)>0;
54
dis03 = lin04.DistanceTo(List.FilterByBoolMask(vtx01,bln05<1><2>)["in"]);
55
lin06 = lin04.Translate(vct03,List.MinimumItem(dis03));
56
57
//Largest Rectangle
58
lin07 = List.Transpose([lin05,lin06]);
59
edg01 = List.FirstItem(lin07<1>);
60
edg02 = List.LastItem(lin07<1>);
61
pnt08 = List.Transpose(List.Transpose([edg01.StartPoint,edg01.EndPoint,edg02.EndPoint,edg02.StartPoint])<1>);
62
rct01 = Rectangle.ByCornerPoints(pnt08);
63
are01 = rct01.Patch().Area;
64
rct02 = List.LastItem(List.SortByKey(rct01<1>,are01<1>)["sorted list"]<1>);
65
return rct02;
66
};
67
Copied!
1
def Divs(srf:var[]..[])
2
{
3
divs = [Imperative]
4
{
5
c = 0;
6
r = [];
7
n = true;
8
s = [];
9
while (n)
10
{
11
r [c] = Rect(srf);
12
sld01 = Surface.ByPatch(List.Flatten(r[c],-1));
13
sld02 = Solid.ByUnion(Surface.Thicken(sld01,10));
14
s [c] = Surface.SubtractFrom(srf,sld02);
15
srf = List.Flatten(s[c],-1);
16
n = List.Count(List.Flatten(r[c],-1))>0;
17
c = c+1;
18
19
}
20
rct01 = List.DropItems(List.Flatten(r,-1),-1);
21
prm01 = (List.LastItem(List.DropItems(List.Flatten(s,-1),-1)).Explode());
22
return [rct01,prm01];
23
}
24
crv01 = PolyCurve.ByJoinedCurves(divs[1].PerimeterCurves());
25
crv02 = List.Flatten([divs[0],crv01],1);
26
27
28
return crv02;
29
};
Copied!
RectangularDivision.zip
8KB
Binary
Dynamo 2.9
Copy link