4
$\begingroup$

By definition, the interior point is a point inside an arbitrary region like this:

enter image description here

In picture above, $y$ is an interior point of region. My question is how to find the distance of an interior point from it's boundary?

I have this Idea: By using the polygons, we can approximate the perimeter of region by a n-gon (n is large enough). Then by saving the coordinates of perimeter in two vectors, say $x$ and $y$, and use Nearest command we can find nearest point of perimeter from interior point ($y$).

I created data matrices (find from here) in MATLAB and import to Mathematica.

imp = Import["PI.mat", "LabeledData"];
X = "KP" /. imp;
Y = "KI" /. imp;

But I can't know how to use Nearest command when we have large vectors like X and Y :

Nearest[{Flatten@X, Flatten@Y}, {3, 1.5}]

An error appears, because Flatten@X, Flatten@Y and {3, 1.5} are not the same length.

$\endgroup$
3
  • 2
    $\begingroup$ Not bad idea, not sure exactly what is in X Y but maybe you want: Nearest[Transpose@{X, Y}, {1.5, 3}]? $\endgroup$
    – Kuba
    Commented Feb 3, 2014 at 8:22
  • $\begingroup$ @Kuba X` and Y are two simple vectors. I used that, but not sure it's correct. But what does it (Transpose) do? $\endgroup$ Commented Feb 3, 2014 at 8:32
  • $\begingroup$ Did you look at RegionDistance and SignedRegionDistance? $\endgroup$ Commented Aug 11, 2023 at 14:29

4 Answers 4

4
$\begingroup$

Assuming I interpreted your data correctly...

imp = Import["C:\\Users\\Rasher\\Downloads\\" <> "PI.mat", "LabeledData"];

(* get data into flat lists *)
X = "KP" /. imp // Flatten;
Y = "KI" /. imp // Flatten;

(* turn into X,Y point-sets *)
pts = Transpose[{X, Y}];

(* Find some point to boundary of poly *)
Nearest[pts, {3, 1.5}]

(*  {{2.67062, 2.7767}}   *)
$\endgroup$
12
  • $\begingroup$ Sorry I made a mistake. Please correct {1.5,3} to {3,1.5}. ({1.5,3} is not interior point) Thanks for detailed answer. $\endgroup$ Commented Feb 3, 2014 at 8:40
  • $\begingroup$ I think it is not sufficient to compute the distance to the nearest point since the nearest line may be considerably closer. $\endgroup$
    – Mr.Wizard
    Commented Feb 3, 2014 at 9:08
  • $\begingroup$ @user2667048:done $\endgroup$
    – ciao
    Commented Feb 3, 2014 at 9:09
  • 1
    $\begingroup$ @Mr.Wizard: No, you're interpreting it right, I read the question as the OP wants the nearest point contained in the point-set. If in fact the OP means the nearest point of the connected polygon described by the point-set, my answer is not want they want (hence my caveat re: interpretation), and I'll delete it. $\endgroup$
    – ciao
    Commented Feb 3, 2014 at 9:38
  • 1
    $\begingroup$ @rasher Actually no, you interpreted well. But how can we find nearest point from polygon line in a simple way? $\endgroup$ Commented Feb 4, 2014 at 12:48
8
$\begingroup$

You can compute the distance to all points within the shape in a single pass using DistanceTransform. I was unable to load your data file in Mathematica 7 so I will use an arbitrary shape as an example:

bsf = BSplineFunction[{{0, 0}, {1, 0}, {2, .5}, {1, 1}, {0, 1}}, SplineClosed -> True];

pts = Table[bsf[x], {x, 0, 1, 0.01}];

gr =
 Graphics[{White, Polygon[pts]},
  Background -> Black,
  ImageMargins -> 0,
  PlotRangePadding -> 0,
  ImageSize -> 500
 ]

dist = ImageData @ DistanceTransform[gr];

dist // MatrixPlot

enter image description here

enter image description here

Obviously extracting the correct value(s) will take some scaling, but I don't have time at the moment to work it out. Look at Rescale however.

$\endgroup$
3
$\begingroup$

RegionNearest can also be an option

imp = Import["C:\\Users\\Ali Hashmi\\Downloads\\PI.mat","LabeledData"];
X = "KP" /. imp;
Y = "KI" /. imp;
threadeddata = Transpose[{Flatten@X, Flatten@Y}];
RegionNearest[Line@threadeddata, {3, 1.5}]

(* {2.67041, 2.77665} *)
$\endgroup$
0
$\begingroup$

Since the original data is not accessible anymore, a boundary is setup using CirclePoints with randomness added. After that BSplineFunction is used to create a smooth contour. Discretizing the graphic sets up the region.

SeedRandom[1234];
n = 6; (* Can experiment with more points *)
(pts = CirclePoints[{2, 0}, n]
   + RandomReal[1, {n, 2}]);(*//ListPlot[#,AspectRatio->Automatic]&*)

bsf = BSplineFunction[pts, SplineClosed -> True];
g1 = ListLinePlot[Table[bsf[x]
    , {x, 0, 1, 0.01}]
   , AspectRatio -> Automatic];
mreg = DiscretizeGraphics[g1];

Manipulate[
 Show@{
   Region[Style[mreg, Black], Frame -> True]
   , Graphics[{
     {Red, AbsolutePointSize[6], 
      Point@{x + r Cos[θ], y + r Sin[θ]}
      , {Blue, AbsolutePointSize[6]
       , Point@
        RegionNearest[mreg, {x + r Cos[θ], y + r Sin[θ]}]
       , {Black, Dashed, Circle[{x, y}, r]}
       }
      }
     }
    , Frame -> True]
   }
 , {{x, 0.7}, -1 + r, 2.5 - r}
 , {{y, 0.5}, -1 + r, 2.5 - r}
 , {{r, 0.5}, 0.01, 1.2}
 , {{θ, 0}, 0, 2 π}
 , TrackedSymbols :> All
 ]

enter image description here

$\endgroup$

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.