# Change appearance of ConvexHullMesh

I'm struggling to understand the behaviour of ConvexHullMesh (or rather the non-behaviour). I have a polygon p

p = { {0, 0}, {1, 0}, {1/2, 1/2}, {1, 1}, {0, 1}}


which I can display in a nice way like by e.g.:

Show[Graphics[{LightBlue, EdgeForm[Gray], Polygon[p]}],  Graphics[ {PointSize[Large], Red, Point[#]}] & /@ p]


Now I construct the convex hull

q = ConvexHullMesh[p];


which displays a somewhat featureless rectangle. Having a closer look at q

q // InputForm


I get

BoundaryMeshRegion[{{0., 0.}, {0., 1.}, {1., 0.}, {1., 1.}}, {Line[{{1, 3}, {3, 4}, {4, 2}, {2, 1}}]}, Method -> {"EliminateUnusedCoordinates" -> True, DeleteDuplicateCoordinates" -> Automatic, "VertexAlias" -> Identity, "CheckOrientation" -> True, "CoplanarityTolerance" -> Automatic, "CheckIntersections" -> Automatic, "BoundaryNesting" -> {{0, 0}}, "SeparateBoundaries" -> False, "PropagateMarkers" -> True, "Hash" -> 1136472811504667718}]

so the obvious (?) idea is to replace the head of q (i.e. BoundaryMeshRegion) by a suitably defined function f that uses the argument to display the convex hull in a 'nicer' way. Ignoring the exact implementation of f, the 'usual' way fails, as

f @@ q


just redisplays the rectangle. Head[q] gives the expected BoundaryMeshRegion, but Apply (or @@) somehow fails to replace the head. Similarly, the alternative q[[1]] to access the argument of the head fails.

What am I missing?

Or to be more precise:

• How do I change the appearance of ConvexHullMesh?

• Why does the above solution not work?

While the answers provided so far are nice, it seems like there should be easier ways to achieve this. And there are, I will show two ways: 1) Keeping your ConvexHullMesh as a BoundaryMeshRegion object and (2 converting to a Graphics object.

SeedRandom[0]
pts = RandomReal[4, {200, 3}];
chull = ConvexHullMesh[pts];


First we use HighlightMesh with no need to recreate the MeshRegion:

HighlightMesh[chull, {Style[0, Directive[PointSize[0.015], Red]],
Style[1, Thin, Blue], Style[2, Opacity[0.5], Yellow]}]


Note the use of Style to style the various dimensions (0 for vertices, 1 for edges and 2 for facets. Also note that this object is still a BoundaryMeshRegion and you can compute other nice mesh-related properties from it.

Now the Graphics object approach.

Graphics3D[GraphicsComplex[MeshCoordinates[chull], {PointSize[0.02], Red,
MeshCells[chull, 0], Blue, MeshCells[chull, 1], Green, MeshCells[chull, 2]}],
Boxed -> False]


Note the use of the already available properties of the MeshRegion. No need to use Show here.

• @RunnyKine...thanks for this wonderful and illustrative, general (and best answer) +1...mine was a hack on the fly... Aug 24, 2014 at 19:13
• @ubpdqn, Thanks for the up-vote. I thought this was worth sharing since it's not obvious at first how to style these Mesh objects directly. Aug 24, 2014 at 19:19
• I am still negotiating MMA10 and the computational geometry features...so very happy to learn more.,,so excellent answer Aug 24, 2014 at 19:24
• Thank you, this is exactly what I was looking for. +1 Sep 12, 2014 at 15:34

Show allows you to convert to Graphics object:

Graphics[Show[ConvexHullMesh[p]][[1]] /. {Directive[x_] :>
Directive[{Red, EdgeForm[{Black, Thickness[0.02]}]}]}]


Or perhaps a little more interesting:

pts = RandomReal[{0, 1}, {50, 2}];
g = Graphics[{Red, PointSize[0.03], Point[pts]}];
ch = Show[ConvexHullMesh[pts]][[1]] /. {Directive[x_] :>
Directive[{Yellow, EdgeForm[{Black, Thickness[0.02]}]}]};
Show[Graphics[ch], g]


• Now that is cool. Thanks a lot. Now, any idea why my 'Apply'-idea doesn't work? Aug 24, 2014 at 14:39

Why the above solution (f@@q) doesn't work?

Because a MeshRegion is an AtomQ.

How do I change the appearance of ConvexHullMesh?

Because

The convex hull region is the smallest convex region that includes the points

the computed and returned ConvexHullMesh is of course correct. Because you are computing the convex hull, maybe it's because you are interested to show the input list of points and their convex hull. You can use Show to combine directly a MeshRegion with another Graphics.

Maybe you are interested to DelaunayMesh, related with but different from ConvexHullMesh (returns a MeshRegion instead of a BoundaryMeshRegion).

p = {{0, 0}, {1, 0}, {1/2, 1/2}, {1, 1}, {0, 1}};
q = ConvexHullMesh[p];
{Show[q, Graphics@Point@p], HighlightMesh[DelaunayMesh[p], Style[0, Red]]}


p = {{0, 0}, {1, 0}, {1/2, 1/2}, {1, 1}, {0, 1}};

Show[

ConvexHullMesh[p],

HighlightMesh[
MeshRegion[p, Polygon[Range@Length@p],
MeshCellStyle -> {2, All} -> Opacity[0.5, Orange]],
Labeled[0, "Index"]]]


While converting to a Graphics object or using HighlightMesh may be more flexible, you don't need to. To obtain a similar style as the OP Graphics object, one could just add options to the ConvexHullMesh call. Here is the OP Graphics object:

Show[
Graphics[{LightBlue, EdgeForm[Gray], Polygon[p]}],
Graphics[{PointSize[Large], Red, Point[p]}]
]


And here's a similar output using ConvexHullMesh:

ConvexHullMesh[
p,
MeshCellStyle->{
0->Directive[PointSize[Large],Red],
1->Gray,
2->LightBlue
}
]


For some settings of the option PlotTheme various cells are more visible:

Grid @ Partition[Labeled[ConvexHullMesh[p, ImageSize -> 250, Frame -> False,
PlotTheme -> #], Style[#, 24], Top]& /@
{"Business", "Web", "Marketing", "Classic","Scientific","Detailed",
"Points","Lines", "Polygons"}, 3]