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.

This is partly a math question, partly a Mathematica question.

For educational purposes, I'm making a simple demonstration to create a velocity over time graph from six locators. On the basis of input from the user in the velocity graph (he moves the graph control points), a distance over time graph and an acceleration over time graph will be automatically produced through integration and differentiation.

Trouble is, a piecewise linear function leaves corners for which the derivative is undefined. There is also a real-world issue: an object cannot instantaneously jump from an acceleration of 2 to 3. I would like the velocity function to "round" the corners.

I don't want to use Bezier or BSpline because the control points do not lie on the graph of the function.

I suspect that Fit will be of use, but I'm unsure what model to use that will have the function intersect with the points where the locators are positioned.

Suggetions about the math (which model) and/or the Mathematica code are appreciated.

Here's a simplified version of the code:

velocity over time graph

Manipulate[
 LocatorPane[
  Dynamic[pts, (pts = #; 
     pts = Function[
        pnt, {.25 Round[4 pnt[[1]]], .1 Round[10 pnt[[2]]]}] /@ 
       pts) &],
  data = (Sort@pts);
  Dynamic@Show[{ListPlot[{data},
      ImageSize -> 550,
      Joined -> True,
      AspectRatio -> 1/2,
      Epilog -> 
       Dynamic@MapIndexed[Text[#2[[1]], Offset[{5, 10}, #1]] &, 
         data],
      BaseStyle -> 12,
      AxesLabel -> {"time (min)", "velocity \n(m/s)("},
      PlotRange -> {{0, 30}, {-20, 20}}, Axes -> True, 
      ImageSize -> 450]}]],

 {{pts, {{0, 0}, {4, 12}, {7, 12}, {23, -12}, {25, -12}, {27, -6}}}, 
  ControlType -> None}]
share|improve this question
    
Can't you just use interpolation with order 2 or more? –  rm -rf Jun 27 '13 at 14:23
    
I have never used Interpolation but a quick reading of the documentation suggests that this may be indeed what I need. Would you like to elaborate on your suggestion as an answer to the question? –  David Carraher Jun 27 '13 at 14:28
3  
You can also take a look on Locator documentation. Properties & Relations example 2. –  Kuba Jun 27 '13 at 14:38
    
@Kuba Example 2 is Locator[Dynamic[{x,y}]] will reset the values of x and y when the locator object is moved; Locator[{x,y}] will not. I don't see the relation to the question.(The code correctly uses Dynamic.) Perhaps you can explain. –  David Carraher Jun 27 '13 at 15:23
    
I am confused, I do not know where is this quote from. Documentation for Locator/Properties & Relations/, second example is about "Use LocatorPane to use locators on complex objects:" which is related. Not by syntax but by interpolation of points. –  Kuba Jun 27 '13 at 16:13

1 Answer 1

up vote 6 down vote accepted

As mentioned in the comments, using Interpolation[] is likely your best bet. It behaves strangely with certain location positions, but still makes for a useful demonstration.

Manipulate[LocatorPane[Dynamic[pts, (pts = #;
     pts = 
      Function[pnt, {.25 Round[4 pnt[[1]]], .1 Round[10 pnt[[2]]]}] /@
        pts) &], data = (Sort@pts);
  fx = Interpolation[pts, x, InterpolationOrder -> 5];
  Dynamic@
   Grid[{{Show[{ListPlot[pts, ImageSize -> 550, AspectRatio -> 1/2, 
         Epilog -> 
          Dynamic@MapIndexed[Text[#2[[1]], Offset[{5, 10}, #1]] &, 
            data], BaseStyle -> 12, 
         AxesLabel -> {"time (s)", "velocity \n(m/s)"}, 
         PlotRange -> {{0, 30}, {-20, 20}}], 
        Plot[fx, {x, Min[pts[[All, 1]]], 
          Max[pts[[All, 1]]]}]}]}, {Plot[
       Evaluate[D[fx, x]], {x, Min[pts[[All, 1]]], 
        Max[pts[[All, 1]]]}, ImageSize -> 550, AspectRatio -> 1/2, 
       BaseStyle -> 12, 
       AxesLabel -> {"time (s)", "acceleration \n(m/s^2)"}, 
       PlotRange -> {{0, 30}, Automatic}]},
     {Plot[
       Evaluate[Integrate[fx, x]], {x, Min[pts[[All, 1]]], 
        Max[pts[[All, 1]]]}, ImageSize -> 550, AspectRatio -> 1/2, 
       BaseStyle -> 12, 
       AxesLabel -> {"time (s)", "displacement \n(m)"}, 
       PlotRange -> {{0, 30}, Automatic}]}}]], {{pts, {{0, 0}, {4, 
     12}, {7, 12}, {23, -12}, {25, -12}, {27, -6}}}, 
  ControlType -> None}]

plots

share|improve this answer
1  
Shouldn't your third plot be labeled "distance" on its y-axis and not "velocity"? –  m_goldberg Jun 27 '13 at 15:17
    
It was labelled that way in the code but I forgot to change the screenshot. Fixed. –  Corey Kelly Jun 27 '13 at 15:25
    
Still a small error: displacement should have units (m) not (m/s). –  m_goldberg Jun 27 '13 at 15:31
    
Are the units even consistent? Since the original plot was (m/s) vs (min), there should be some factors of 60 floating around. –  Corey Kelly Jun 27 '13 at 15:40
    
Since the Manipulate is for educational purposes, I think changing it to the m-k-s system is fine. –  m_goldberg Jun 27 '13 at 15:44

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.