# Why does RegionDifference fail with crescent polygon (V10)?

Posted 1 month ago
262 Views
|
7 Replies
|
3 Total Likes
|
 I’m trying to create a difference region by finding the difference between a rectangle and a crescent shape (fig. [a]) created by modifying Bezier data for a circle. The crescent is a polygon based on points created with BezierFunction[]. The goal is to use the difference region to mask out images of lines such as the diagonal where it extends beyond the border of the crescent in figure [a]. In a previous project, I was successful with RegionDifference[rectangle, disc] and RegionDifference[polygon, polygon] using simple polygons defined by three and four points as in figure [c], but using the crescent polygon as a region I fail with RegionDifference[polygon, polygon] and RegionDifference[polygon, rectangle] with the arguments in any order. Figure [b] provides an example. The error message is {RegionDifference[Polygon[(…)],Polygon[(<<1>>)]]} is not a valid region to plot. >> It seems that RegionDifference[] does not accept the list of points for the crescent as the basis for a valid Polygon[] region. The list appears to be uncomplicated. I would like to know why and find a solution.Mathematica 10.0.0.0 OS 10.9.5 sz = 1.5; (* rect corner dimension *) c = 0.551915024494; (* Bezier constant for circle *) bz = {{0, 1}, {c, 1}, {1, c}, {1, 0}}; (* Bezier control points *) bzF = BezierFunction[bz]; bzFPts = Table[bzF[t], {t, 0, 1, .1}]; crescentPts = AppendTo[bzFPts, bzFPts[[1]]]; (* illustrate the crescent with figure and ground but without RegionDifference[] *) crescentPolygon = {EdgeForm@Black, FaceForm@White, Polygon[crescentPts]}; background = {EdgeForm@Black, FaceForm@LightGray, Rectangle[{-sz, -sz}, {sz, sz}]}; figure = Line[{{-1, -1}, {1, 1}}]; g1 = Graphics[{background, crescentPolygon, figure, Text["[a]", {-.75, .75}]}, ImageSize -> {100, 100}]; (* RegionDifference between gray background and white crescent *) rectanglePts = {{-sz, -sz}, {-sz, sz}, {sz, sz}, {sz, -sz}, {-sz, -sz}}; regionDiffCrescent = First@RegionPlot@RegionDifference[ Polygon@rectanglePts, Polygon@crescentPts ]; (* remove the default directives from new region *) maskCrescent = DeleteCases[regionDiffCrescent, _Directive, -1]; g2 = Graphics[{figure, FaceForm@LightGray, maskCrescent, Text["[b]", {-.75, .75}]}, ImageSize -> {100, 100}]; (* region diff with triangle works properly *) regionDiffTriangle = First@RegionPlot@RegionDifference[ Polygon@rectanglePts, Polygon@{{-1, 0}, {0, 1}, {1, 0}, {-1, 0}}]; maskTriangle = DeleteCases[regionDiffTriangle, _Directive, -1]; g3 = Graphics[{figure, FaceForm@LightGray, maskTriangle, Text["[c]", {-.75, .75}]}, ImageSize -> {100, 100}]; Show[GraphicsRow[{g1, g2, g3}, Background -> White]] 
7 Replies
Sort By:
Posted 1 month ago
 If you have version 12 you can try out the new "polygon with holes" feature: Graphics[Polygon[{{0, 0}, {1, 0}, {1, 1}, {0, 1}} -> crescentPolygon[[3, 1]]]] 
Posted 1 month ago
 The new feature is good to know about, but I'm still using version 10. Can one conclude that DifferenceRegion also fails with these Bezier data in version 12?
Posted 1 month ago
 Your code gives no error on my system. Can you give a piece of code that does not work?
Posted 1 month ago
 The requested piece of code is the code for g2 which produced figure [b]. Does my code produce in your system a figure [b] with a white crescent with a diagonal line through it as in the triangle in figure [c]? If so, then I would conclude that the problem is the MMA 10 rather than with the code. I have isolated the code for figure [b]. sz = 1.5; (* rect corner dimension *) c = 0.551915024494; (* Bezier constant for circle *) bz = {{0, 1}, {c, 1}, {1, c}, {1, 0}};(* Bezier control points *) bzF = BezierFunction@bz; bzFPts = Table[bzF[t], {t, 0, 1, .1}]; crescentPts = AppendTo[bzFPts, bzFPts[[1]]]; figure = Line[{{-1, -1}, {1, 1}}]; rectanglePts = {{-sz, -sz}, {-sz, sz}, {sz, sz}, {sz, -sz}, {-sz, -sz}}; (* error message generated here *) regionDiffCrescent = First@RegionPlot@RegionDifference[ Polygon@rectanglePts, Polygon@crescentPts ] ; (* remove the default directives from new region *) maskCrescent = DeleteCases[regionDiffCrescent, _Directive, -1]; g2 = Graphics[{figure, FaceForm@LightGray, maskCrescent, Text["[b]", {-.75, .75}]}, ImageSize -> {100, 100}] 
Posted 1 month ago
 On my system your maskCrescent is not really a mask with the crescent as a hole. It is a superposition of polygons that covers the whole of the square. I don't know what happens in version 10. I suspect that something goes wrong when we convert a Region with a hole into graphics primitives with RegionPlot. I get quite different pictures from the following inputs: RegionDifference[Polygon@rectanglePts, Polygon@crescentPts] RegionPlot@% On my system the whole problem somehow goes away if I insert DiscretizeRegion before RegionPlot: regionDiffCrescent = First@RegionPlot@ DiscretizeRegion@ RegionDifference[Polygon@rectanglePts, Polygon@crescentPts];