I'd like to compute the union of a collection of outlines in MetaPost. I'm aware of the buildcycle
macro (in combination with cutbefore
and cutafter
). However, that macro is not very useful because I don't know the shapes I want to join in advance, so it's difficult to predict how to "build" the cycles.
To complicate matters, some parts of the paths are very thin, which causes problems with rounding.
I'm aware of this related question but ideally I need a MetaPost solution.
The following is a possible example. The paths were actually computed using MetaPost and the union was also computed with MetaPost. Still, the way it was done wasn't ideal. I'd like to have a more robust solution.
beginfig(0);
% Some paths
draw (12.47017,32.24423)..controls (6.40797,28.74423) and (2.43744,20.24191)
..(0,0.39084)..controls (0.86858,1.25941) and (1.73717,2.128)
..(2.60574,2.99658)..controls (5.04318,22.84766) and (9.59935,30.58676)
..(15.66154,34.08676)..controls (14.59775,33.47258) and (13.53397,32.85841)
..cycle withpen pencircle scaled 0.2pt;
draw (15.66154,34.08676)..controls (9.59935,30.58676) and (5.04318,22.84766)
..(2.60574,2.99658)..controls (2.73602,2.8663) and (2.8663,2.73602)
..(2.99658,2.60574)..controls (5.43402,22.45682) and (9.87572,30.1081)
..(15.93791,33.6081)..controls (15.8458,33.76765) and (15.75366,33.9272)
..cycle withpen pencircle scaled 0.2pt;
draw (12.74654,31.76556)..controls (6.68434,28.26556) and (2.82828,19.85107)
..(0.39084,0)..controls (1.25941,0.86858) and (2.128,1.73717)
..(2.99658,2.60574)..controls (5.43402,22.45682) and (9.87572,30.1081)
..(15.93791,33.6081)..controls (14.87411,32.99391) and (13.81033,32.37975)
..cycle withpen pencircle scaled 0.2pt;
draw (12.47017,32.24423)..controls (6.40797,28.74423) and (2.43744,20.24191)
..(0,0.39084)..controls (0.13028,0.26056) and (0.26056,0.13028)
..(0.39084,0)..controls (2.82828,19.85107) and (6.68434,28.26556)
..(12.74654,31.76556)..controls (12.65442,31.92513) and (12.56229,32.08467)
..cycle withpen pencircle scaled 0.2pt;
draw (2.60574,2.99658)..controls (3.14021,7.34944) and (3.7446,12.08865)
..(5.58054,15.14981)..controls (5.58057,15.14986) and (5.58061,15.14992)
..(5.58064,15.14996)..controls (6.39726,15.58105) and (7.34497,15.81947)
..(8.4495,15.81947)..controls (9.31807,16.68805) and (10.18666,17.55664)
..(11.05524,18.42522)..controls (9.19986,18.42522) and (7.78699,17.75247)
..(6.69463,16.62376)..controls (5.84612,15.74702) and (4.95805,14.90953)
..(4.10631,14.03595)..controls (1.36111,11.22037) and (0.63171,5.53574)
..(0,0.39084)..controls (0.86858,1.25941) and (1.73717,2.128)
..cycle withpen pencircle scaled 0.2pt;
draw (2.60574,2.99658)..controls (2.73602,2.8663) and (2.8663,2.73602)
..(2.99658,2.60574)..controls (3.87912,9.79335) and (4.95229,18.03438)
..(11.44608,18.03438)..controls (11.3158,18.16466) and (11.18552,18.29494)
..(11.05524,18.42522)..controls (4.56145,18.42522) and (3.48828,10.18419)
..cycle withpen pencircle scaled 0.2pt;
draw (2.99658,2.60574)..controls (3.53105,6.9586) and (4.13544,11.69781)
..(5.97137,14.75897)..controls (5.9714,14.75902) and (5.97145,14.75908)
..(5.97148,14.75912)..controls (6.7881,15.19022) and (7.73581,15.42863)
..(8.84033,15.42863)..controls (9.70891,16.29721) and (10.5775,17.1658)
..(11.44608,18.03438)..controls (9.5907,18.03438) and (8.17783,17.36163)
..(7.08546,16.23293)..controls (6.23695,15.35619) and (5.34889,14.51869)
..(4.49715,13.64511)..controls (1.75195,10.82953) and (1.02255,5.1449)
..(0.39084,0)..controls (1.25941,0.86858) and (2.128,1.73717)
..cycle withpen pencircle scaled 0.2pt;
draw (0,0.39084)..controls (0.13028,0.26056) and (0.26056,0.13028)
..(0.39084,0)..controls (1.27338,7.1876) and (2.34654,15.42863)
..(8.84033,15.42863)..controls (8.71005,15.55891) and (8.57977,15.6892)
..(8.4495,15.81947)..controls (1.9557,15.81947) and (0.88254,7.57845)
..cycle withpen pencircle scaled 0.2pt;
draw (11.05524,18.42522)..controls (10.18666,17.55664) and (9.31807,16.68805)
..(8.4495,15.81947)..controls (14.4495,15.81947) and (12.27396,10.31638)
..(11.05524,0.39084)..controls (11.92381,1.25941) and (12.7924,2.128)
..(13.66098,2.99658)..controls (14.8797,12.92212) and (17.05524,18.42522)
..cycle withpen pencircle scaled 0.2pt;
draw (11.44608,18.03438)..controls (12.74173,18.03438) and (13.65614,17.77776)
..(14.2813,17.2754)..controls (14.28131,17.2754) and (14.28131,17.2754)
..(14.28133,17.2754)..controls (15.96465,15.1815) and (14.55524,10.27959)
..(13.66098,2.99658)..controls (13.79126,2.8663) and (13.92154,2.73602)
..(14.05182,2.60574)..controls (14.90062,9.5186) and (16.21355,14.28624)
..(14.90535,16.5436)..controls (14.57936,17.10611) and (14.11217,17.57391)
..(13.54927,17.89926)..controls (12.94624,18.2478) and (12.13252,18.42522)
..(11.05524,18.42522)..controls (11.18552,18.29494) and (11.3158,18.16466)
..cycle withpen pencircle scaled 0.2pt;
draw (11.44608,18.03438)..controls (10.5775,17.1658) and (9.70891,16.29721)
..(8.84033,15.42863)..controls (14.84033,15.42863) and (12.6648,9.92554)
..(11.44608,0)..controls (12.31465,0.86858) and (13.18324,1.73717)
..(14.05182,2.60574)..controls (15.27054,12.53128) and (17.44608,18.03438)
..cycle withpen pencircle scaled 0.2pt;
draw (8.84033,15.42863)..controls (10.13599,15.42863) and (11.0504,15.17201)
..(11.67555,14.66966)..controls (11.67557,14.66966) and (11.67557,14.66966)
..(11.67558,14.66966)..controls (13.3589,12.57576) and (11.9495,7.67384)
..(11.05524,0.39084)..controls (11.18552,0.26056) and (11.3158,0.13028)
..(11.44608,0)..controls (12.29488,6.91286) and (13.6078,11.6805)
..(12.2996,13.93785)..controls (11.97362,14.50037) and (11.50642,14.96817)
..(10.94353,15.29352)..controls (10.3405,15.64206) and (9.52678,15.81947)
..(8.4495,15.81947)..controls (8.57977,15.6892) and (8.71005,15.55891)
..cycle withpen pencircle scaled 0.2pt;
% The union
draw (8.84033,15.42863)..controls (10.13599,15.42863) and (11.0504,15.17201)
..(11.67555,14.66966)..controls (13.35896,12.57596) and (11.94951,7.674)
..(11.05524,0.39084)..controls (11.18552,0.26056) and (11.3158,0.13028)
..(11.44608,0)..controls (12.31465,0.86858) and (13.18324,1.73717)
..(14.05182,2.60574)..controls (14.90062,9.51855) and (16.21353,14.2862)
..(14.90535,16.5436)..controls (14.58578,17.09502) and (14.13054,17.55544)
..(13.58244,17.87985)..controls (13.00317,18.2351) and (12.17043,18.42522)
..(11.05524,18.42522)..controls (9.19986,18.42522) and (7.78699,17.75247)
..(6.69463,16.62376)..controls (6.18193,16.09401) and (5.6548,15.57858)
..(5.12996,15.06087)..controls (7.69498,25.93929) and (11.35297,30.96098)
..(15.93791,33.6081)..controls (15.8458,33.76765) and (15.75366,33.9272)
..(15.66154,34.08676)..controls (14.59775,33.47258) and (13.53397,32.85841)
..(12.47017,32.24423)..controls (6.80194,28.97168) and (2.96234,21.32587)
..(0.49504,4.12018)..controls (0.30708,2.87721) and (0.15076,1.61865)
..(0,0.39084)..controls (0.13028,0.26056) and (0.26056,0.13028)
..(0.39084,0)..controls (1.25941,0.86858) and (2.128,1.73717)
..(2.99658,2.60574)..controls (3.19746,4.24173) and (3.41196,5.79485)
..(3.63985,7.2692)..controls (4.11122,10.09549) and (4.78354,12.77844)
..(5.97137,14.75897)..controls (6.78725,15.19) and (7.7353,15.42863)
..cycle withcolor red withpen pencircle scaled 0.1pt;
endfig;
end;
FWIW: If you're wondering, I'm making a calligraphic font, which I'm hoping to showcase for the TUG calendar, 2015. The font is based on my handwriting. The h above is a crude approximation:-)
penpos
command that defines the pen slant at a given position. The lack of built-in MetaPost support for path unions is disappointing as it's something that is almost always needed.