Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Edit: This question turned out to be two parts so I am going to make this question about only the first part a kguler provided an excellent answer.

Here is a better representation. My actual data consists of many points which I bin onto a grid.

data = RandomVariate[NormalDistribution[1, 3], {10^5, 3}];
rounded = Round@data;
gathered = Gather[rounded];
offset = -Min /@ Transpose@rounded + 1;
counts = Length /@ gathered;
(*I offset the data so I can use SparseArray from 1*)
coords = offset + # & /@ (First /@ gathered); 
sparesearray = SparseArray[coords -> counts];

Each grid contains the count of the number of points that were in the grid cube (voxel). I now create a contour plot.

ListContourPlot3D[sparesearray, Contours -> {2.5}]

Mathematica graphics

In this case its ugly since its random data. However, in my real data it has discrete volumes. I want to find the points in the original data (or the offset data).

I could simply use the bins with more than n counts but I was hoping to take advantage of the interpolation that ListContourPlot3D uses.

How do I extract the polygons rendered by ListContourPlot3D?

early version below for posterity:

I have a set of data points in 3D and I want to extract the subset of points that is contained within the surface generated by a contour plot.

data = Table[x^2 + y^2 + z^2 + RandomReal[0.1], {x, -2, 2, 0.2}, {y, -2, 2, 
  0.2}, {z, -2, 2, 0.2}]

The sample data here is on a regular grid but my real data is not on a regular grid. It is defined: (x, y, z, value).

plot = ListContourPlot3D[data, Contours -> {1}, Mesh -> None]

Mathematica graphics

InputForm returns a GraphicsComplex object but I'm not really sure how to determine the polygons in the surface and then how to determine which of the points are inside the surface and which are outside.

share|improve this question
1  
I'm not sure I understand the question: isn't this just selecting those {x,y,z} points from your dataset for which value is in a given range? (For your example $\text{value} \in [0,1]$ because the contour is at $1$) –  Szabolcs Feb 19 '13 at 4:32
    
@Szabolcs, in simplifying my problem to a question I think I made it too simple. Please see edits. –  s0rce Feb 19 '13 at 4:57

1 Answer 1

up vote 6 down vote accepted

From the Documentation Center Normal > Details

Normal[expr] converts GraphicsComplex objects into ordinary lists of graphics primitives and directives.

So, for

  data = Table[x^2 + y^2 + z^2 + RandomReal[0.1], {x, -2, 2, 0.2}, 
    {y, -2, 2,  0.2}, {z, -2, 2, 0.2}];
  plot = ListContourPlot3D[data, Contours -> {1}, Mesh -> None,  ImageSize -> 400];

you can get the ordinary list of polygons using

  Cases[Normal[plot[[1]]], Polygon[__], {0, Infinity}]

and

  polygonCoords = 
  Cases[Normal[plot[[1]]], Polygon[x_, ___] :> x, {0, Infinity}]

gives the coordinates of the polygons

enter image description here

grphcs = Graphics3D[{Opacity[.9], EdgeForm[Opacity[.3]], 
Polygon[#,  VertexColors -> Table[Hue[RandomReal[]], {Length[#]}]] & /@ 
 Cases[Normal[plot[[1]]], Polygon[x_, ___] :> x, {0, Infinity}]},
Lighting -> "Neutral", ImageSize -> 400];
Row[{plot, grphcs}]

enter image description here

Update: OP's new example:

 data = RandomVariate[NormalDistribution[1, 3], {10^5, 3}];
 rounded = Round@data; gathered = Gather[rounded];
 offset = -Min /@ Transpose@rounded + 1;
 counts = Length /@ gathered;
 coords = offset + # & /@ (First /@ gathered);
 sparesearray = SparseArray[coords -> counts];

  plot2 = ListContourPlot3D[sparesearray, Contours -> {2.5},  ImageSize -> 400];
  grphcs2 = Graphics3D[{EdgeForm[Opacity[.3]],
   Polygon[#, VertexColors -> Table[Hue[RandomReal[]], {Length[#]}]] & /@ 
  Cases[Normal[plot2[[1]]], Polygon[x_, ___] :> x, {0, Infinity}]},
   Lighting -> "Neutral", ImageSize -> 400];
  Row[{plot2, grphcs2}]

enter image description here

Note: still remains open is the second part of OP's question (determining the sets of points inside and outside the surface).

share|improve this answer
    
+1, so now with the polygons is there a way to determine which of the initial points are within the contained volume? –  s0rce Feb 19 '13 at 16:53
    
@s0rce, thanks for the vote. I am afraid I don't know how to approach the second part of your question:) –  kguler Feb 20 '13 at 0:29

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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