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.

I want to find all data points inside curve as given below:

data = RandomReal[{-1, 1}, {200, 2}];
ParametricPlot[{Sin[u], Sin[2 u]}, {u, 0, 2 Pi}, 
 Epilog -> {Red, Point[data]}]

Short solution is preferable

Thanks.

share|improve this question
    
Related but simpler question: (17306) –  Mr.Wizard Jul 9 at 3:14
    
Also related: How to compile Heike's winding number function? –  Jens Jul 9 at 4:58

4 Answers 4

up vote 11 down vote accepted

Using the answer by rm-f here, you can discretized the curve into a polygon and get the desired points to any arbitrary accuracy:

inPolyQ[poly_, pt_] := Graphics`Mesh`PointWindingNumber[poly, pt] =!= 0

pp = Table[{Sin[u], Sin[2 u]}, {u, 0, 2 Pi, Pi/100}];

inPoints = Select[data, inPolyQ[pp, #] &];

ParametricPlot[{Sin[u], Sin[2 u]}, {u, 0, 2 Pi}, 
 Epilog -> {Red, Point[inPoints]}]

points inside

Edit for version 10

In Mathemtica version 10, the problem of finding points inside a closed curve doesn't have to be reduced to the problem of finding points inside a Polygon obtained from that curve by discretization. Instead, you can use the following symbolic approach which requires only that the curve be specified in a suitable form that can be handled by the new Region... commands:

rf = RegionMember[
   ParametricRegion[{Sin[u], r Sin[2 u]}, {{u, 0, 2 Pi}, {r, 0, 1}}]];

ParametricPlot[{Sin[u], Sin[2 u]}, {u, 0, 2 Pi}, 
 Epilog -> {Red, Point[Pick[data, rf[data]]]}]

region

The problem is solved in one line, completely without explicitly forming a list of boundary points.

share|improve this answer
    
+1 for FGITW :-) –  Mr.Wizard Jul 9 at 2:28
    
@Mr.Wizard Strange that we both waited exactly 48 minutes before answering and then did so simultaneously! –  Jens Jul 9 at 2:31

Compute the points of a polygon and use any of the methods from How to check if a 2D point is in a polygon?. I'll use Simon's inPolyQ2.

g = ParametricPlot[{Sin[u], Sin[2 u]}, {u, 0, 2 Pi}];
poly = Cases[g, Line[x_] :> x, -1][[1]];
inside = Pick[data, inPolyQ2[poly, ##] & @@@ data];
Show[g, Epilog -> {Red, Point@inside}]

enter image description here

share|improve this answer
    
+1 for almost beating me... –  Jens Jul 9 at 2:29
    
@Jens Thanks! For what it's worth I think using the adaptive sampling of ParametricPlot (as I do here) is superior to uniform sampling of Table. Also, inclusion testing could be faster if inPolyQ2 were compiled for the specific polygon thereby eliminating significant redundancy. –  Mr.Wizard Jul 9 at 2:33
    
You're probably right, but I wanted to be as short as possible - that's what Algohi asked for, right? I guess it depends on whether the plot was considered to be already given or not... –  Jens Jul 9 at 2:35
    
@Jens In that case you might as well use ListLinePlot on pp. –  Mr.Wizard Jul 9 at 2:38
2  
But that would have cost me precious extra seconds... –  Jens Jul 9 at 2:45

Another undocumented function (also appeared in the Q/A How to check...):

p = ParametricPlot[{ Sin[u], Sin[2 u]}, {u, 0, 2 Pi}];
Show[p, ListPlot@Pick[#, Graphics`Mesh`InPolygonQ[p[[1, 1, 3, 2, 1]], #] & /@ #] &@data]

enter image description here

share|improve this answer
    
for getting the points out of the plot, I think Leonid method might be more portable than depending on [[1,1,3,2,1]] indexing as this might change in future versions. As in points = Reap[ParametricPlot[{Sin[u], Sin[2 u]}, {u, 0, 2 Pi}, EvaluationMonitor :> Sow[{Sin[u], Sin[2 u]}]]][[2, 1]]; stackoverflow.com/questions/5364088/… –  Nasser Jul 9 at 4:05
    
@Nasser, this is specific to OP's example, and too specific to work generally. –  kguler Jul 9 at 4:40

Here is a contour integral way of determining which points lie inside a closed curve. It has the advantage that it can be applied to any parametric closed contour.

Define the curve corresponding to the parametric curve {Sin[u], Sin[2 u]}.

f[u_] := Sin[u] + I Sin[2 u];

Define the derivative of the curve.

df[u_] = D[f[u], u];

Define the contour integral around a pole at x + I y.

inside[x_, y_] := NIntegrate[df[u]/(f[u] - (x + I y)), {u, 0, 2 \[Pi]}] // Chop[#, 10^-6] & // # != 0 & // Quiet;

For this particular parametric curve this will give zero when the pole is outside the contour, and ±2 Pi I when it is inside the contour.

BTW, I tried doing this contour integral with Integrate (rather than NIntegrate) but the ConditionalExpression produced by Integrate was not correct. Is it a bug, or is it just me? I don't know.

Apply the inside function to some data.

data = RandomReal[{-1, 1}, {200, 2}];
datainside = inside @@@ data;

Plot the result.

ParametricPlot[{Sin[u], Sin[2 u]}, {u, 0, 2 Pi},
  Epilog -> MapThread[{If[#2, Red, Blue], Point[#1]} &, {data, datainside}]]

This approach will generalise straightforwardly to more complicated contours.

share|improve this answer

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.