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.

My problem is:

I want two Locators to simulate a vector in the following sense:

The first Locator is the base and the second the tip of the vector.

When I move the tip, the base does not move (hence the vector changes).

When I move the base, the vector is unchanged, and therefore the tip (and the Locator) moves.

How can I achieve that?

I have tried storing the previous value of the base and then test if the current value is different. And if so updated the position of the tip. I can however not make that work, when using 'Module'. I suspect that there is a more elegant solution.

share|improve this question
1  
This you look at the other related answers? Such as this: mathematica.stackexchange.com/questions/26891/… –  Pickett Aug 13 '13 at 10:36
    
Also related: mathematica.stackexchange.com/questions/22134/… –  Michael E2 Aug 13 '13 at 15:26
add comment

2 Answers

up vote 5 down vote accepted

This seems to be a duplicate but I can't find it :). Meanwhile, you can use second argument of Dynamic.

x = {0, 0}; y = {1, 1}; w = y - x;


Deploy@Graphics[{
                 Locator@Dynamic[x, (x = #; y = x + w;) &],
                 Locator@Dynamic[y, (y = #; w = y - x;) &],
                 Dynamic@Arrow[{x, y}]
                }
                , PlotRange -> 2]

In case of multiple vectors one may want to save space and make code more transparent so we can use extended version of Dynamic second argument to achieve this:

Deploy@Graphics[{
                 Locator@Dynamic[x, {(w = y - x;) &, (x = #; y = x + w) &, None}],
                 Locator@Dynamic[y],
                 Dynamic@Arrow[{x, y}]
                }
               , PlotRange -> 2]

Now we are working only with base, moreover w can be scoped to particular Locator.

There is huge advantage of the second method, well, not exactly the method but the usage of f_start and f_end. You can calculate w once, not all the time you are dragging the Locator.

share|improve this answer
    
+1 I like this answer a lot and a learned something from it! btw. while I researched it I noticed that the exact number of times w is calculated in the second version is twice every time you drag that locator. (Method; first n=0; and then inside the anonymous function Print[n++]). –  Pickett Aug 13 '13 at 13:41
    
@Anon Indeed, I saw this too with Print. Do you know why it is so? –  Kuba Aug 13 '13 at 13:45
    
No! I became very curious but I suppose there is no good answer. It's not what is says in the documentation so I guess that's just "how it is". –  Pickett Aug 13 '13 at 13:47
add comment
p1save = {0, 0}; p2save = {1, 1};
Manipulate[
        If[p1 != p1save, p2 = p2 + p1 - p1save; p1save = p1];
        Graphics[Arrow[{p1, p2}], PlotRange -> {{-5, 5}, {-5, 5}}, AspectRatio -> 1],
 {{p1, p1save}, Locator}, {{p2, p2save}, Locator}
 ]

or a little bit more sophisticated, preventing the arrow to overflow the graphics window:

p1save = {0, 0}; p2save = {1, 1};  min = -5; max = 5;
Manipulate[
 If[Or @@ ((min > # || # > max) & /@ Flatten[{p1, p2 + p1 - p1save}]),
                                               p1 = p1save; p2 = p2save];
 If[p1 != p1save, p2 = p2 + p1 - p1save; p1save = p1; p2save = p2];
 Graphics[Arrow[{p1, p2}], PlotRange -> {{min, max}, {min, max}},  AspectRatio -> 1],
 {{p1, p1save}, Locator}, {{p2, p2save}, Locator}
 ]
share|improve this answer
    
Looking good. But somehow in the second example if I move the base of the arrow, the head of the arrow moves at constant speed. –  Jacob Akkerboom Aug 15 '13 at 21:22
add comment

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.