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
?
-
$\begingroup$ I can't find one. Related question: mathematica.stackexchange.com/q/20105 $\endgroup$– Michael E2Nov 14, 2013 at 0:29
2 Answers
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_] :=
Max@ImageData@
Rasterize@
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:
RegionPlot3D[
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$– MichaelNov 14, 2013 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-34Nov 14, 2013 at 15:34
-
$\begingroup$ Ah, very nice. By the way, what do you mean by "just draw the point"? $\endgroup$– MichaelNov 14, 2013 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-34Nov 14, 2013 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]
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}}]