5
$\begingroup$

I would like to make different components of my 3D regions show in different colors (colours). Here are some dimensions for a bolt, washer and plate. I can make the individual components in different colors but when I assemble them (the last graphic) they are all in the same default color.

Len = 150/1000;  (*length of plate  *)
ht = 15/1000; (* height *)
wd = 80/1000; (* width *)
rh = 1/2 11/1000; (* hole radius *)
rb = 1/2 10/1000;(* bolt shaft radius *)
rwi = 1/2 (105/10)/1000; (* washer inner radius *)
rwo = 1/2 21/1000; (* washer outside radius *)
hw = 2/1000; (* washer thickness *)
rhd = 1/2 17/1000;(* head radius *)
Lh = (718/100)/1000;(* head length *)

reg1 = BoundaryDiscretizeRegion[
  Cuboid[{-Len/2, -wd/2, 0}, {Len/2, wd/2, ht}], 
  MeshCellStyle -> Orange];(* plate *)
reg2 = BoundaryDiscretizeRegion[
  Cylinder[{{0, 0, -ht}, {0, 0, 2 ht}}, rh]];  (* hole*)
reg3 = RegionDifference[reg1, reg2, MeshCellStyle -> {Darker[Orange]}]
reg4 = BoundaryDiscretizeRegion[
  Cylinder[{{0, 0, 0}, {0, 0, ht + hw}}, rb]]; (* bolt shank *)
reg5 = BoundaryDiscretizeRegion[
  Cylinder[{{0, 0, ht + hw}, {0, 0, ht + hw + Lh}}, 
   rhd]];  (* bolt head *)
reg6 = RegionUnion[reg4, reg5, MeshCellStyle -> {Darker[Green]}]
reg7 = BoundaryDiscretizeRegion[
  Cylinder[{{0, 0, ht}, {0, 0, ht + hw}}, rwo]]; (* washer *)
reg8 = BoundaryDiscretizeRegion[
  Cylinder[{{0, 0, ht}, {0, 0, ht + hw}}, rwi]]; (* washer hole*)
reg9 = RegionDifference[reg7, reg8, MeshCellStyle -> {Darker[Yellow]}]
reg = RegionUnion[reg3, reg6, reg9]

Mathematica graphics

Mathematica graphics

Mathematica graphics

Mathematica graphics

How can I make each component (bolt, washer and plate) have different colors? Thanks

Edit

Chip Hurst makes the good suggestion that if it is just for display then Show can be used

Show[reg3, reg6, reg9]

Mathematica graphics

This is actually very useful. If I turn the plate over I can examine the quality of the clearance between the bolt and the hole.

$\endgroup$
  • 4
    $\begingroup$ If it’s just for display you can use Show instead of RegionUnion. Also FYI if you use PlotTheme -> “Minimal” the edges and points will be hidden. $\endgroup$ – Chip Hurst May 19 at 16:46
  • $\begingroup$ @ChipHurst I am putting the regions together to make a mesh. However, your suggestion of using Show is a good one if I just wish to examine the assembly. Also, thanks for the PlotTheme idea. $\endgroup$ – Hugh May 19 at 16:49
  • $\begingroup$ For my own clarification: did you position these by hand then? Or use a Mathematica function to “fit” them together by just not allowing the Regions to overlap? This is awesome seeing some CAD type work in an unmodified mma environment!! Very pretty :D $\endgroup$ – CA Trevillian May 21 at 13:23
  • 1
    $\begingroup$ @CATrevillian It turns out to be very straightforward. All the code is given above. For this case I actually gave the dimensions for each component from the same datum. They then fit together when you apply RegionUnion. However, I could have built them using a different datum for each component. Then in order to assemble them you would have to apply translations and rotations so that they all come together properly. With the color added this makes for good CAD. $\endgroup$ – Hugh May 21 at 15:09
  • $\begingroup$ This is quite impressive, then! (not that it wasn't before, but hey!) Clarification ( not another question, ;D ): By datum, you refer to your initial definitions? This, to me, is truly Shakespeare's defined use of awesome, when I say, "This is AWESOME!!!" I want to recommend, even though I hardly even lurk there (for now, anyway!), that you should post this on Community, they would eat this up! Although packaging it up with a UI would be really time-consuming, but fun!!! $\endgroup$ – CA Trevillian May 21 at 18:54
6
$\begingroup$

One approach is to see where each face in the union came from and assign the colors from there.

rmfs = RegionMember /@ {reg3, reg6, reg9};

color[{__, True}] = Darker[Yellow];
color[{_, True, _}] = Darker[Green];
color[_] = Darker[Orange];

centroids = PropertyValue[{reg, 2}, MeshCellCentroid];

facecolors = color /@ Transpose[Through[rmfs[centroids]]];

styles = {2, #[[All, 1]]} -> #[[1, 2]] & /@ 
  GatherBy[Transpose[{Range[MeshCellCount[reg, 2]], facecolors}], Last];

BoundaryMeshRegion[reg, MeshCellStyle -> styles]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.