I noticed in this question, Behavior of Graphics`Mesh`InPolygonQ with self-intersecting polygons, that Mathematica has some "psuedo-hidden" functionality for allowing one to quickly perform a winding number calculation to tell if a point is inside of a polygon mesh. As a shot in the dark, is there built-in functionality to detect if a point sits in a 3D graphics primitive like Cylinder?


The answer is there in your question! You make a shot in the dark [cylinder], then see if you can see your shot outside.

IsInsideShape[point_, shape_] := 
  Graphics3D[{Lighting -> {{"Point", White, point}}, shape}, 
   ViewPoint -> point, Boxed -> False, Background -> Black] == 0;

With a dense machine-gun fire you can trace the outline of your object:

 IsInsideShape[{x, y, z}, Cylinder[]], {x, -1, 1}, {y, -1, 1}, {z, -1,
   1}, PlotPoints -> 5, MaxRecursion -> 0]

Though I'll admit, it's a tad slow.

  • $\begingroup$ Very cool. =) So the ViewPoint setting rotates the point to the foreground, and Mathematica checks to see if it should light the point based on whether it's inside or outside the tube? Do I have that right? Awesome hack. $\endgroup$ – Michael Nov 14 '13 at 15:24
  • $\begingroup$ @Michael, the point is used as a light source and I check to see if it lights the cylinder's surface, I rotate the viewpoint so that the lighted area should face the viewer. Of course, simpler (and probably faster) would be to just draw that point without any lighting, but that wouldn't be as faithful a representation of 'shots in the dark'. $\endgroup$ – panda-34 Nov 14 '13 at 15:34
  • $\begingroup$ Ah, very nice. By the way, what do you mean by "just draw the point"? $\endgroup$ – Michael Nov 14 '13 at 15:36
  • $\begingroup$ Well, by draw I mean draw, like in Graphics3D[{Lighting -> None, shape, White, Point@point}, ViewPoint -> point, Boxed -> False, Background -> Black]. But then, you'll have issues with the points lying on the surface... $\endgroup$ – panda-34 Nov 14 '13 at 15:43

In Version 10 there is such a function. Meet RegionMember.

We take your Cylinder primitive as an example:

cyl = Cylinder[]

Let's create some points:

pts = RandomReal[{-1.5, 1.5}, {100, 3}];

Now we create a RegionMemberFunction that can be used repeatedly on various points.

mf = RegionMember[cyl]

Mathematica graphics

We apply mf to the set of points and give them different colors based on whether they fall inside or outside the Cylinder

color = mf[pts] /. {True -> Red, False -> Black};

Let's visualize:

Graphics3D[{{Opacity[0.4], cyl}, Transpose @ {color, Point /@ pts}}]

Mathematica graphics


Your Answer

