25

Bread has a bubbly texture that I would like to be able to recreate using Mathematica.

Here are some examples of bubble textures:

  • Bread

bread

  • Swiss cheese

Swiss cheese

  • Foam

foam

Note that most of the bubbles are ellipsoids or more complex 3D forms (only 'isolated' bubbles in the second case are approximately spherical). Bubbles generally do not intersect but are deformable by each other (and by the original 'pre-cut' boundary of the object - e.g. in the case of bread). Closely spaced bubbles approach polyhedrons with a minimum curvature at the 'vertices' (like 3D Voronoi texture).

I can generate a bunch of spheres intersecting a cube easily using something like:

Graphics3D[{Cuboid[{-2, -2, -5}, {8, 10, 10}], 
Sphere[RandomReal[10, {500, 3}], RandomReal[{0.1, 1}]]}]

my attempt

But I can't see how to variably change their shape or allow them to deform without intersecting. Ultimately I'm looking to make bubbles that are deformed by each other and the 'pre-cut' boundary of the solid. I am thinking that one way to visualise this would be generate the bubbles (for example, within a 'pre-cut loaf' shape) and combining this with a surface slice using ParametricPlot3D to end up with something like this:

fake bread

(but with nice bubbles inside!)

I realise that it may be non-trivial to work out how the bubbles deform...

Also, it would be nice to be able to add colours and 2D textures to the different surfaces to, for example, brown the crust, add wholemeal flakes etc.

How would one go about creating a semi-realistic bubble texture intersecting a 3D surface and/or volume?

(P.S - Not entirely relevant but there are some inspiring forms here and here)

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
geordie
  • 3,693
  • 1
  • 26
  • 33

1 Answers1

28

Here's a rather simple first attempt using RegionPlot3D to define a solid with Voronoi cell type voids.

I start with a set of random void locations. The region function says that a point is in the solid if the distance to the nearest void centre is almost the same as the distance to the second nearest void centre (i.e. we are close to a Voronoi cell boundary), or if the distance to the nearest void centre is greater than some threshold.

pts = RandomReal[{-1, 1}, {200, 3}];   
nf = Nearest[pts];

r[x_, y_, z_] := Module[{d1, d2},
  {d1, d2} = EuclideanDistance[{x, y, z}, #] & /@ nf[{x, y, z}, 2];
  d1 > 0.3 || d2 - d1 < 0.05]

RegionPlot3D[r[x, y, z], {x, -1, 1}, {y, -1, 1}, {z, -1, 1}, 
 Mesh -> None, Boxed -> False, Axes -> False, BoxRatios -> Automatic, PlotPoints -> 50]

enter image description here

While being some way from resembling bread, I think with some tweaking one could make an acceptable Swiss cheese using this approach.

Simon Woods
  • 84,945
  • 8
  • 175
  • 324
  • 1
    +1. Very nice. Probably to get bread one would have to model the tension in the dough. – Michael E2 Jun 04 '13 at 16:02
  • Some changes are necessary to make this work in current versions: nf = Nearest[pts -> "Distance"]; rr[t_, h_][x_?NumberQ, y_?NumberQ, z_?NumberQ] := (#1 > t || #2 - #1 < h) & @@ nf[{x, y, z}, 2]; RegionPlot3D[rr[3/10, 1/20][x, y, z], {x, -1, 1}, {y, -1, 1}, {z, -1, 1}, Axes -> None, Boxed -> False, BoxRatios -> Automatic, Mesh -> None, PlotPoints -> 50, PlotStyle -> ColorData[97, 2]] – J. M.'s missing motivation May 10 '20 at 04:42