4
$\begingroup$

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}]
$\endgroup$
6
  • $\begingroup$ Can't you just use interpolation with order 2 or more? $\endgroup$
    – rm -rf
    Jun 27, 2013 at 14:23
  • $\begingroup$ 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? $\endgroup$
    – DavidC
    Jun 27, 2013 at 14:28
  • 3
    $\begingroup$ You can also take a look on Locator documentation. Properties & Relations example 2. $\endgroup$
    – Kuba
    Jun 27, 2013 at 14:38
  • $\begingroup$ @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. $\endgroup$
    – DavidC
    Jun 27, 2013 at 15:23
  • $\begingroup$ 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. $\endgroup$
    – Kuba
    Jun 27, 2013 at 16:13

1 Answer 1

8
$\begingroup$

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

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

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.