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.

I am confused by Dynamic. I am trying to slide a tangent line along a curve, without using DynamicModule, so that I can include it in a cdf. I have the sliding point working in the below, but the tangent line is static. How do I get the line moving as well?

LocatorPane[
 Dynamic[pt],
 plot1 = Plot[Sin[x], {x, 0, 10},
   Epilog -> {
     PointSize[Large],
     Point[Dynamic[{First[pt], Sin[First[pt]]}]]
     }];
 TangentAngle = Cos[First[pt]];
 x1 = First[pt] - 0.5*Cos[TangentAngle];
 y1 = pt[[2]] - 0.5*Sin[TangentAngle];
 x2 = First[pt] + Cos[TangentAngle];
 y2 = pt[[2]] + Sin[TangentAngle];

 plot2 = Graphics[Line[{Dynamic[{x1, y1}], Dynamic[{x2, y2}]}]];
 Show[{plot1, plot2}], Appearance -> None
 ]
share|improve this question
1  
The answers to this question should be quite helpful : mathematica.stackexchange.com/questions/10669/… –  Artes Jan 20 '13 at 2:10

4 Answers 4

up vote 3 down vote accepted
LocatorPane[Dynamic[pt, (pt = {#[[1]], Sin[#[[1]]]}) &],
Dynamic@Plot[{Sin[x],
ConditionalExpression[Cos[pt[[1]]]*(x - pt[[1]]) + Sin[pt[[1]]],
 pt[[1]] - 1 <= x <= pt[[1]] + 1]}, {x, 0, 10},
PlotRange -> {{-2, 11}, {-2, 2}},
Epilog -> {PointSize[Large], Point[pt]}],
Appearance -> None]

enter image description here

For arbitrary function func, replace Cos with Derivative[1][func] in the first argument of ConditionalExpression.

Instead of Epilog -> {PointSize[Large], Point[pt]}], one can also use

Mesh -> {{pt[[1]]}}, MeshStyle -> PointSize[Large]]

Update: Using Locator as a graphics primitive, one can get the same result without having to use LocatorPane:

Dynamic@Plot[{Sin[x],
ConditionalExpression[Cos[pt[[1]]]*(x - pt[[1]]) + Sin[pt[[1]]],
pt[[1]] - 1 <= x <= pt[[1]] + 1]}, {x, 0, 10},
PlotRange -> {{-2, 11}, {-2, 2}},
Epilog ->  Dynamic@{Locator[Dynamic[pt, (pt = {#[[1]], Sin[#[[1]]]}) &],
  Graphics[{Black, PointSize[Large], Point[pt]}]]}]
share|improve this answer
    
very elegant. Thanks. –  jamie Jan 20 '13 at 13:17
    
Thanks for the suggestion of Derivative as well as your other suggestions. The last option using Dynamic@Plot works in a notebook but unfortunately does not work in a CDF. –  jamie Jan 20 '13 at 14:07
    
You need to use the piece Dynamic@Plot.. as the first argument in Manipulate[..., {dummycontrol, None}] for it to work in a CDF. Thank you for the accept. And welcome to MathematicaSE. –  kguler Jan 20 '13 at 14:50

The only way I could make your code work was to introduce a helper function. I have no experience with CDFs, but I would hope they allow such functions.

tangent[pt_] := Module[{tanAngle, xy1, xy2},
  tanAngle = ArcTan@Cos[pt[[1]]];
  xy1 = pt - 0.5 {Cos[tanAngle], Sin[tanAngle]};
  xy2 = pt + 0.5 {Cos[tanAngle], Sin[tanAngle]};
  Graphics[{Line[{xy1, xy2}]}]]

LocatorPane[
  Dynamic[pt, (pt = With[{ptx = #[[1]]}, {ptx, Sin@ptx}]) &], 
  plot = Plot[Sin[x], {x, 0, 10}, 
    Epilog -> {PointSize[Large], Dynamic@Point[pt]}];
  Dynamic@Show[{plot, tangent[pt]}], Appearance -> None]

tangent demo

Note the introduction of ArcTan in the calculation of the tangent angle and the use of the second argument of Dynamic in the locator pane.

Note: the second argument of Dynamic provides a way to constrain the movement of the locator. I use it to confine the locator to the curve.

share|improve this answer

@m_goldberg: thanks for spotting the 'ArcTan'. Sine was not the best function to do this on. Unfortunately, i did not get your solution to work in a CDF.

However, with your suggestion and reading through the link from @Artes, my messy code has morphed into something that works:

LocatorPane[
Dynamic[pt],
 plot1 = Plot[Sin[x], {x, 0, 10}, PlotRange -> {{-2, 11}, {-2, 2}},
  Epilog -> {
 PointSize[Large],
 Point[Dynamic[{First[pt], Sin[First[pt]]}]],
 Line[Dynamic[{
    {First[pt] - Cos[ArcTan[Cos[First[pt]]]],
     Sin[First[pt]] - Sin[ArcTan[Cos[First[pt]]]]
     },
    {First[pt] + Cos[ArcTan[Cos[First[pt]]]],
     Sin[First[pt]] + Sin[ArcTan[Cos[First[pt]]]]
     }
    }]]}
 ], Appearance -> None]

output

Thanks

share|improve this answer

I first thought to make this a comment, but I wanted to give an example for the OP to test: DynamicModule is supported by CDF Player, or at least the code below works on both the v8 and v9 CDF Player. (It's a little more elaborate than what the OP proposed, but I wanted to test a few things and decided to leave them in.)

DynamicModule[{a = 1.5, f = Sin, tangetLine, x1 = 0, x2 = 10}, 
 tangetLine[x_, a0_] := f[a0] + f'[a0] (x - a0);
 Labeled[LocatorPane[
   Dynamic[{a, f[a]}, (a = Clip[#[[1]], {x1, x2}]) &],
   Dynamic@Plot[f[x], {x, x1, x2}, PlotRange -> 1, PlotRangePadding -> {1, 0.2},
     Epilog -> {Line[{#, tangetLine[#, a]} & /@
                 {a - 1/Sqrt[1 + f'[a]^2], a + 1/Sqrt[1 + f'[a]^2]}]}, 
     AspectRatio -> Automatic],
   Appearance -> Graphics[{PointSize[Large], Point[{0, 0}]}]],
  SetterBar[
   Dynamic[f], # -> TraditionalForm[#[x]] & /@
    {Sin, Cos, # ((#/π)^2 - 1) (#/(2 π) - 1) (#/(3 π) - 1) (#/(4 π) - 1) &},
   Alignment -> Center],
  Top]
]

output

Notes:

  1. A tangent line one unit long in each direction seems to be desired. But if the scales on the axes aren't the same, then the tangent line will appear to change length. So I include AspectRatio -> Automatic just in case. (Cos[ArcTan[f'[a]]] simplifies to 1/Sqrt[1+f'[a]^2].)

  2. I clipped the Locator position to the domain {x1, x2} to constrain it to the domain passed to Plot.

  3. The option Alignment turns red in SetterBar, but it seems to get passed to the component Setters without generating errors. (To get rid of the SetterBar, copy the LocatorPane[..] code and paste it over the Labeled[..] code

  4. There is also this Demonstration that moves tangents, as well as secants, whose code could be adapted. CDFs support Manipulate, too.

share|improve this answer

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.