2
$\begingroup$

I'm trying to create a function that uses a dynamic locatorpane to populate a list with the coordinates of user defined locators (added by alt+clicking). This code works fine:

one = ExampleData[{"TestImage", "Airplane"}] ptsa = {}; ptsb = {}; Button["Reset points", ptsa = {}] LocatorPane[Dynamic[ptsa], Dynamic[ Show[one, Graphics[{ Table[(*draw arrows between locators*) Arrow[{ ptsa[[i]], ptsa[[i + 1]] }], {i, 1, Floor[Length[ptsa], 2], 2} ], Table[ Text[(i + 1)/2, ptsa[[i]] + (ptsa[[i + 1]] - ptsa[[i]])/2 + Cross[ptsa[[i + 1]] - ptsa[[i]]]/ EuclideanDistance[ptsa[[i + 1]], ptsa[[i]]]*10],(*display line # 5 pixels orthogonal to line \ midpoint*) {i, 1, Floor[Length[ptsa], 2], 2} ] }] ] ], LocatorAutoCreate -> True, Appearance -> Style["\[CenterDot]", Medium, Red]] 

That works for the single list: "ptsa" and allows me to insert points into "ptsa" with a point-and-click interface.

However, I need to do this for many different lists (ptsb, ptsc, ptsd, etc). I tried making a function ui[ptsa_] := LocatorPane[...] so I can just do ui[ptsb] in the future, but this simply inserts {} into ptsa, which doesn't help.

I also tried defining the above simply as a = LocatorPane[...] and trying

a /. ptsa -> ptsb 

but that doesn't work either. I'm not sure how to approach this.

$\endgroup$
4
  • $\begingroup$ Welcome to MMA.SE. Please try to provide a minimal working example for you questions in the future. The LocatorPane and other details are not relevant there. Please take a look at HoldFirst documentation's examples, I believe there is the answer to your question. $\endgroup$ Commented Apr 6, 2016 at 5:37
  • 4
    $\begingroup$ I'm voting to close this question as off-topic because it is to localized. $\endgroup$ Commented Apr 8, 2016 at 8:02
  • 1
    $\begingroup$ @Kuba. I don't agree. It's a simple question with a simple answer, but it certainly is an issue that often comes up. $\endgroup$ Commented Apr 8, 2016 at 13:57
  • $\begingroup$ @m_goldberg that's probably arguable :) I think it is in OP's reach to reduce the problem to drop Locator/Graphics context, yet my comment was left without any answer. That's why I voted to close as too localized. Furthermore, after reducing the problem what stays is a simple mistake or a duplicate candidate. $\endgroup$ Commented Apr 8, 2016 at 14:25

1 Answer 1

3
$\begingroup$

All you have to do is give ui the attribute HoldFirst. It also a good idea to make the image an argument of ui. That is, define

SetAttributes[ui, HoldFirst]; ui[pts_, img_Image] := LocatorPane[ Dynamic[pts], Dynamic[ Show[ img, Graphics[ {Table[ Arrow[{pts[[i]], pts[[i + 1]]}], {i, 1, Floor[Length[pts], 2], 2}], Table[ Text[ (i + 1)/2, pts[[i]] + (pts[[i + 1]] - pts[[i]])/2 + Cross[pts[[i + 1]] - pts[[i]]] / EuclideanDistance[pts[[i + 1]], pts[[i]]]*10], {i, 1, Floor[Length[pts], 2], 2}]}]]], LocatorAutoCreate -> True, Appearance -> Style["\[CenterDot]", Medium, Red]] 

Then

ptsa = {}; ui[ptsa, one] 

image

Dynamic @ ptsa

{{231.6, 158.5}, {213.2, 74.}, {70.8, 130.}, {156.4, 83.5}}

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.