1
$\begingroup$

I am putting together a Manipulate on vector addition for my intro physics class and everything works well except when I include a Graphics that has a Table within. The code is below. There are three controls for each vector; two sliders x1, and y1 for the vector components and a Locator p1 at the head of the vector. In the code you'll see second arguments of Dynamics that link the Locator coordinates p1 and the vector components x1 and y1. There is a second vector that starts at the head of the first and has similar controls associated with it. There are several Graphics that I've left out that don't matter. What I left in here are curved arrows to show the standard angle for each vector. The Arrows are created using Table as you can see.

If you Show just the two vectors, as I have in the code below, everything works perfectly. As you move the Locator or the Sliders for one vector the other vector does not change magnitude or direction.

If I include the angle arrow for vector 1, angleArrow1, in the Show command it still works perfectly. However, if I include the angle arrow for vector 2, angleArrow2, in Show the Locator at the head of vector 2 acts as if it is the Locator for vector 1. In other words, when I move the Locator at the head of vector 2 only vector 1 changes. However, moving the sliders for vector 2 works as do the sliders and Locator for vector 1.

What is weird is that if I use the commented out version of angleArrow2 that doesn't use Table, but uses an explicit list, it works! I need Table to generate the list because I need an arc that grows as the angle grows and remains fairly smooth looking.

So what is it about Table (and only in the angleArrow for vector 2) that is causing it to in effect link the two Locators? I've tried putting the angleArrow creation function into an Initialization at the end of the Manipulate and calling it when needed, but it still doesn't work. I've tried wrapping Evaluate around Table, or around Arrow, but still no help. I'll keep tinkering, but this has really got me stumped.

Thanks!

Manipulate[(*The second argument of the Dymanics below allows us to \
link the Locator with variable p (={x,y}) to the two sliders with \
variables x and y.*)

 theta1 = 
  Which[y1 >= 0, ArcCos[x1/Sqrt[p1.p1]], y1 < 0, 
   2 Pi - ArcCos[x1/Sqrt[p1.p1]]];
 vector1 = 
  Graphics[{Green, Arrow[{{0, 0}, p1}], 
    Locator[Dynamic[
      p1, (p1 = #; {x1 = p1[[1]], y1 = p1[[2]], 
         p2[[1]] = p1[[1]] + x2, p2[[2]] = p1[[2]] + y2}; #) &]]}]; 
 angleArrow1 = 
  Graphics[Arrow[
    Table[Min[0.5 Sqrt[p1.p1], 0.5] {Cos[j], Sin[j]}, {j, 0, theta1, 
      1/100}]]];

 (*Stuff for vector 2*)

 theta2 = Which[y2 >= 0, ArcCos[x2/Sqrt[x2^2 + y2^2]], y2 < 0, 
   2 Pi - ArcCos[x2/Sqrt[x2^2 + y2^2]]];

 vector2 = 
  Graphics[{Green, Arrow[{p1, p2}], 
    Locator[Dynamic[
      p2, (p2 = #; {x2 = p2[[1]] - p1[[1]], 
         y2 = p2[[2]] - p1[[2]]}; #) &]]}];

 (*angleArrow2=Graphics[Arrow[{{x1+Min[0.5 Sqrt[x2^2+y2^2],0.5] 
Cos[0],y1 +Min[0.5 Sqrt[x2^2+y2^2],0.5] Sin[0]},{x1+Min[0.5 
Sqrt[x2^2+y2^2],0.5] Cos[theta2/2],y1 +Min[0.5 Sqrt[x2^2+y2^2],0.5] 
Sin[theta2/2]},{x1+Min[0.5 Sqrt[x2^2+y2^2],0.5] Cos[theta2],y1 
+Min[0.5 Sqrt[x2^2+y2^2],0.5] Sin[theta2]}}]];*)

 angleArrow2 = 
  Graphics[Arrow[
    Table[{x1 + Min[0.5 Sqrt[x2^2 + y2^2], 0.5] Cos[j], 
      y1 + Min[0.5 Sqrt[x2^2 + y2^2], 0.5] Sin[j]}, {j, 0, theta2, 
      1/100}]]];

 (*Combine All The Graphics*)

 Show[{vector1, vector2}, 
  PlotRange -> {{-4.1, 4.1}, {-4.1, 4.1}}, ImageSize -> 500],

 (*Controls*)

 Row[{"Ax",
    Manipulator[
    Dynamic[x1, (x1 = #; {p1[[1]] = x1, p2[[1]] = x1 + x2}; #) &], {-4, 4}],
   Spacer[4], 
   Dynamic[Style[Round[x1, 0.001], 14]]}], 
 Row[{"Ay",
    Manipulator[
    Dynamic[y1, (y1 = #; {p1[[2]] = y1, p2[[2]] = y1 + y2}; #) &], {-4, 4}],
   Spacer[4], 
   Dynamic[Style[Round[y1, 0.001], 14]]}], 
 Row[{"Bx",
    Manipulator[
    Dynamic[x2, (x2 = #; p2[[1]] = x1 + x2; #) &], {-4, 4}], 
   Spacer[4], Dynamic[Style[Round[x2, 0.001], 14]]}], 
 Row[{"By",
    Manipulator[
    Dynamic[y2, (y2 = #; p2[[2]] = y1 + y2; #) &], {-4, 4}], 
   Spacer[4], 
   Dynamic[Style[Round[y2, 0.001], 14]]}], 
 {{p1, {1.5, 1.5}},None},
 {{p2, {1.5 + Cos[Pi/6], 1.5 + Sin[Pi/6]}}, None},
 {{x1, 1.5},None},
 {{y1, 1.5}, None},
 {{x2, Cos[Pi/6]},None},
 {{y2, Sin[Pi/6]}, None},
 {{theta1, Pi/4}, None},
 {{theta2, Pi/6}, None}, TrackedSymbols -> {x1, y1, p1, x2, y2, p2}]
$\endgroup$
5
  • $\begingroup$ I can also see no different behaviour in the two angleArrow2 methods after I have added the missing } to angleArrow1. $\endgroup$
    – Matariki
    Commented Feb 28, 2012 at 21:18
  • $\begingroup$ This is what I see; what am I supposed to see? $\endgroup$
    – Mr.Wizard
    Commented Feb 28, 2012 at 23:10
  • $\begingroup$ @Szabolcs, I'm sorry for the length of the code (I could have left off some of the control display formatting), but I wanted to include a complete sample so someone could cut and paste into Mathematica and replicate my result. I've edited out the extraneous { in angleArrow1 (it isn't there in my Mathematica code so it wasn't the problem. It crept in when I pasted the code into my post here - I apologize). $\endgroup$ Commented Feb 29, 2012 at 0:09
  • $\begingroup$ Again, I have to apologize. I should have been more clear. When you include only vector1 and vector2 (and even angleArrow1) into Show, as Show[{vector1,vector2,angleArrow1}...] everything works fine. The Locator for each vector changes the magnitude and direction of only that vector and the sliders for only that vector change. The problem is that when you add angleArrow2 to the Show command (Show[{vector1,vector2,angleArrow1,angleArrow2},...]) the second vector can't be changed by its Locator, but it can be changed by its sliders. $\endgroup$ Commented Feb 29, 2012 at 1:59
  • $\begingroup$ What is weird is that if you use the definition for angleArrow2 that does not use Table (commented out in the code above) then it works. However, not using Table makes it difficult to get a nice looking curved arrow. @kguler I tried various Deployed options and wrapping Show in Deploy, but that didn't fix it. It did help avoid getting an edit box around the graphics if you didn't click right on the Locator, but it didn't fix my problem. $\endgroup$ Commented Feb 29, 2012 at 2:02

1 Answer 1

2
$\begingroup$

Ok, I figured it out, sort-of. Here is what was in my original code for the curved Arrow that indicates the angle for the second vector:

angleArrow2 = 
  Graphics[Arrow[Table[{x1 + Min[0.5 Sqrt[x2^2 + y2^2], 0.5] Cos[i], 
      y1 + Min[0.5 Sqrt[x2^2 + y2^2], 0.5] Sin[i]}, {i, 0, theta2, 
      1/100}]]];

The problem was not necessarily with Table, but with the Table iterator. I kept asking myself why the commented-out definition of angleArrow2 worked when the definition with Table did not. I realized that the only difference between the two versions of angleArrow2 was the number of elements in the list within Arrow. So I started to play with the step size in the Table iterator. As I made the step size larger to reduce the number of elements in the list I started to see a hint of correct behavior. In other words, moving the Locator for the second vector DID move only the second vector, but only for a short "time". Once I moved the Locator beyond a certain distance (that seemed to depend on the step size in Table) the unwanted behavior appeared again. I.e. the second Locator moved along with the first Locator and changed the size and direction of the first vector instead of the second.

With a fixed step size such as 1/100 as I originally had, or even 1/10 as I eventually tried, the unwanted behavior eventually appeared. So I decided to try a relative step size base on the angle (theta2) and changed my code to read:

angleArrow2 = 
  Graphics[Arrow[Table[{x1 + Min[0.5 Sqrt[x2^2 + y2^2], 0.5] Cos[i], 
      y1 + Min[0.5 Sqrt[x2^2 + y2^2], 0.5] Sin[i]}, {i, 0, theta2, 
      theta2/20}]]];

Now it works beautifully! When one Locator is moved only its associated vector is changed.

Now, I haven't quite figured out why this works, but a little more thinking may help. If anyone has any ideas on why an absolute step size resulted in the unwanted behavior while a relative step size worked correctly I would love to hear from you. However, I think you really need to evaluate my code at various absolute step sizes to see what I mean. With an absolute step size like 1/10 when you move the second Locator you initially see only the second vector changing, but then suddenly the first vector starts changing instead. Weird!

If you do evaluate my code be sure to Show the two vectors and the angle for the second vector:

Show[{vector1, vector2, angleArrow2}, PlotRange -> {{-4.1, 4.1}, {-4.1, 4.1}}, 
 ImageSize -> 500]

Thank you everyone for your suggestions!

$\endgroup$
2
  • $\begingroup$ I'm glad you figure this out, it was driving me crazy :) I'm keen to hear an explanation for why this worked as well. I had tracked the problem down to theta2 in the Table but I couldn't seem to fix it. $\endgroup$
    – Andy Ross
    Commented Feb 29, 2012 at 6:03
  • $\begingroup$ Well, as I played around to try to figure out why I get this weird behavior when the Table iterator step size is absolute instead of relative, I found that wrapping Show in Deploy to prevent graphics editing (if the user slightly misses the Locator when they click the get the dreaded red box around the graphics) cause the problem to return. I.e. the Locator no longer moves correctly even when using relative step size. I'm thinking now that it might have something to do with how I've linked the Locator and Sliders. I'm going to post a simpler question to try to get at the root cause of this. $\endgroup$ Commented Feb 29, 2012 at 20:32

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.