0
$\begingroup$

I assume this is a simple task, yet I could not find any documentation or question treating this problem:

Let's say we have a simple binary data set, in this case defining a shape of a circle

data = Flatten[Table[{x, y, If[x^2 + y^2 < 1, 1, 0]}, {x, -2, 2, 0.1}, {y, -2, 2, 0.1}], 1];
ListDensityPlot[data, InterpolationOrder -> 0]

Now I want to have the points forming the boundary of this object, in coordinates {{x1,y1},{x2,y2},...}.

It seems to be exactly what EdgeDetect is doing, but that function does not accept data points, only images. Is there a similar function for data points?

These posts are related, but not the same in my opinion:

  1. Finding edges of a parametrized function
  2. Finding the edge of the plot area
  3. Finding the edge of data set

The last question (3) is probably the same but the input data format seems to be different than here and the data is not available anymore.

enter image description here

$\endgroup$
2
  • $\begingroup$ ConvexHullMesh if convex. $\endgroup$
    – george2079
    Feb 2, 2017 at 22:36
  • $\begingroup$ Thanks, but what if it's not convex? $\endgroup$
    – Felix
    Feb 2, 2017 at 22:40

1 Answer 1

2
$\begingroup$

Turn the data into an image, apply EdgeDetect, and (if needed) translate back to ImageData:

data = Table[If[x^2 + y^2 < 1, 1, 0], {x, -2, 2, 0.1}, {y, -2, 2, 0.1}];
edge = EdgeDetect[Image[data]]
edgeData = Table[{(x - 21)/10, (y - 21)/10, 
                 ImageData[edge][[x, y]]}, {x, 41}, {y, 41}];

The final line puts the {x,y} coordinates with the edges.

$\endgroup$
2
  • $\begingroup$ It works. However, I would suggest as a general approach to keep extract the {x,y} coordinates in a slightly different way. The function f[data_, component_] := Reverse[Partition[data[[All, component]], Length[DeleteDuplicates[data[[All, 2]]]]]] extracts one of the components of data and brings it to the {nx,ny} image shape. Then, edgeData =Transpose[{Flatten[f[data,1]], Flatten[f[data,2]], Flatten[ImageData[edge]]}] (where data is defined as in my post). $\endgroup$
    – Felix
    Feb 3, 2017 at 4:32
  • $\begingroup$ Just realized one typo in f. To be robust, it should read f[data_, component_] := Module[{sdata}, sdata = Sort[data, If[#1[[2]] == #2[[2]], #1[[1]] < #2[[1]], #1[[2]] < #2[[2]]] &]; Return[ Reverse[Partition[sdata[[All, component]], Length[DeleteDuplicates[sdata[[All, 1]]]]]]]]; $\endgroup$
    – Felix
    Feb 3, 2017 at 5:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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