I have a plot as below (the plot is just for illustration purpose. in my real problem, I just have pts1):-

pts1 = BlockRandom[SeedRandom[7]; RandomReal[2.9, {30, 2}]];
pts1L = MapThread[Labeled[#1, #2] &, {pts1, Range[Length@pts1]}];
plot1 = ListPlot[pts1L, PlotRange -> {{0, 3.5}, {0, 3}}];
plot2 = ParametricPlot[{3, t}, {t, 0, 3}, PlotStyle -> Darker[Red]];
Show[plot1, plot2]

enter image description here

When I have a vector representing the red line, let say redLine = {0, 0.5, 1, 1.5, 2, 2.5, 3}, I want to have the coordinates of the closet points as output, i.e. {pts1[[17]], pts1[[17]], pts1[[22]], pts1[[9]], pts1[[26]], pts1[[13]], pts1[[6]]} as output.

My current solution is as below, but that's too clumsy and will be very slow when the scale of the problem increase. What are the more efficient ways to get it done? (For example, is it possible to calculate the DistanceMatrix of just "frontline points v.s. red line" instead of "all points v.s. red line"?)

redLine = {0, 0.5, 1, 1.5, 2, 2.5, 3}
redLineCood = Transpose@ArrayFlatten[{ConstantArray[3, Length@redLine], redLine}]
dM = DistanceMatrix[redLineCood, pts1];
min = Min /@ dM;
pts1[[Flatten@MapThread[Position[#1, #2] &, {dM, min}]]]

Many thanks!

  • $\begingroup$ pts1=BlockRandom[SeedRandom[7];RandomReal[2.9,{30,2}]]; redLine={0,0.5,1,1.5,2,2.5,3}; redLineCood=Map[{3,#}&,redLine]; f[p_]:=MinimalBy[pts1,Norm[p-#]&][[1]]; f/@redLineCood $\endgroup$
    – Bill
    Commented Jun 17, 2018 at 0:18
  • $\begingroup$ Thanks. This is so elegant. $\endgroup$
    – H42
    Commented Jun 17, 2018 at 0:59
  • $\begingroup$ If the shortest possible distance from pi to the red line is greater than the greatest possible distance from pj to the red line then pi could be discarded. But that is still roughly an n^2 process of comparing all pi against all pj. I don't see any way of overcoming that. Ah, and redLineCood={3,#}&/@redLine; $\endgroup$
    – Bill
    Commented Jun 17, 2018 at 1:07
  • $\begingroup$ ‘Nearest[pts, #, 1]& /@ Thread[{3, redLine}]’? $\endgroup$
    – kglr
    Commented Jun 17, 2018 at 1:35
  • $\begingroup$ Thanks, Nearest[pts1] /@ Thread[{3, redLine}] works so well! $\endgroup$
    – H42
    Commented Jun 17, 2018 at 1:41

1 Answer 1

 Nearest[pts1] /@ Thread[{3, redLine}]

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.