2
$\begingroup$

Today, I was doing my physics homework. One of the questions was to draw velocity-time and position-time graphs from the acceleration-time graph. So for the first step I draw acceleration-time using Graphics:

a = Plot[{10}, {x, 0, 24}, PlotRange -> {{0, 25}, {7, -3}}]
Show[a, Graphics[{Red, Line[{{0, 0}, {2, 0}}]}], 
Graphics[{Red, Line[{{2, -2}, {6, -2}}]}], 
Graphics[{Red, Line[{{6, 6}, {10, 6}}]}], 
Graphics[{Red, Line[{{10, -2}, {22, -2}}]}], 
Graphics[{Red, Line[{{22, 0}, {24, 0}}]}], 
Graphics[{Black, Dashed, Line[{{2, 0}, {2, -3}}]}], 
Graphics[{Black, Dashed, Line[{{6, 6}, {6, -3}}]}], 
Graphics[{Black, Dashed, Line[{{10, 6}, {10, -3}}]}], 
Graphics[{Black, Dashed, Line[{{22, -3}, {22, 0}}]}], 
Graphics[{Black, Dashed, Line[{{24, -3}, {24, 0}}]}]]

And here is the picture of it:picture

As the question gives us the value of speed in $v_0=3$, I drew it like the previous one (did the calculation on paper):

b = Plot[{100}, {x, 0, 24}, PlotRange -> {{0, 25}, {20, -6}}]
Show[b, Graphics[{Red, Line[{{0, 3}, {2, 3}}]}], 
Graphics[{Red, Line[{{2, 3}, {6, -5}}]}], 
Graphics[{Red, Line[{{6, -5}, {10, 19}}]}], 
Graphics[{Red, Line[{{10, 19}, {22, -5}}]}], 
Graphics[{Red, Line[{{22, -5}, {24, -5}}]}], 
Graphics[{Black, Dashed, Line[{{2, -6}, {2, 20}}]}], 
Graphics[{Black, Dashed, Line[{{6, -6}, {6, 20}}]}], 
Graphics[{Black, Dashed, Line[{{10, -6}, {10, 20}}]}], 
Graphics[{Black, Dashed, Line[{{22, -6}, {22, 20}}]}], 
Graphics[{Black, Dashed, Line[{{24, -6}, {24, 20}}]}], 
Graphics[{Black, Dashed, 
Line[{{2 + (-3/-2), 0}, {2 + (-3/-2), -6}}]}], 
Graphics[{Black, Dashed, Line[{{6 + (5/6), 0}, {6 + (5/6), -6}}]}], 
Graphics[{Black, Dashed, 
Line[{{10 + (-19/-2), 0}, {10 + (-19/-2), -6}}]}]]

And the result: picture

but I was not able to draw position-time, because in most of the time intervals, the shape of the position-time graph is a parabola, which Graphics does not have (as a built-in function).

So I want to know how I can write a function that draws a parabola given by 3 points (parabola minimum or maximum point, and two other points where the parabola starts and ends).

$\endgroup$
  • $\begingroup$ Why are you doing all this with Graphics instead of just using Plot? Seems you are making this harder than it has to be. $\endgroup$ – Jason B. Nov 7 '14 at 10:15
  • $\begingroup$ You may also want to consider integrating the acceleration two times to get s(t). $\endgroup$ – Yves Klett Nov 7 '14 at 10:18
  • $\begingroup$ @JasonB,because in Plot i think we can't draw a line that starts from a specific point and ends in a specific point,can we(I want diagram look good,so I want to have parabola points drawn in specific interval)?My knowledge in mathematica is minimal So i don't know if someone can do such a thing.Anyway, thanks for your attention. $\endgroup$ – user2838619 Nov 7 '14 at 10:21
  • $\begingroup$ @YvesKlett,My problem is in drawing a position-time diagram that looks good(I know how to plot a parabola,but don't know how to plot/draw part of it).I know mathematics related to this topic(Not completely but enough for solving question).If I don't understand what you mean exactly,please say it again. thanks for your attention. $\endgroup$ – user2838619 Nov 7 '14 at 10:26
  • $\begingroup$ For the parabola part, use Plot or a Table to generate your values. Note: you can also pack all graphics primitives (Line etc.) into a single Graphics call to make the code cleaner. As for integrating, that would be directly related to the physics. $\endgroup$ – Yves Klett Nov 7 '14 at 10:37
7
$\begingroup$

If you really want a parabola primitive from 3 points, you can use Fit to fit a parabola to the three points, Plot to plot it, and Cases to extract the Line primitive from the plot. For example

parabola[pts_] := Module[{x, func, xmin, xmax},
  func = Fit[pts, {1, x, x^2}, x];
  xmin = Min[pts[[All, 1]]];
  xmax = Max[pts[[All, 1]]];
  Cases[Plot[func, {x, xmin, xmax}], _Line, -1]]

points = {{10, 10}, {30, 50}, {60, 20}};
Graphics[{
  PointSize[Large], Point[points],
  Red, parabola[points]}]

enter image description here

However, I don't see why you don't just use Plot for everything.

a[t_] = Piecewise[{{-2, 2 <= t < 6}, {6, 6 <= t < 10}, {-2, 10 <= t < 22}}, 0];
v[t_] = 3 + Integrate[a[t], t];
s[t_] = Integrate[v[t], t];

GraphicsRow[
 Plot[#[t], {t, 0, 24},
    Exclusions -> None, PlotRange -> All, PlotLabel -> #]
   & /@ {a, v, s}]

enter image description here

$\endgroup$
  • 1
    $\begingroup$ @SimonWoods...I feel somewhat ashamed of the ugliness of my code...though I like aligning vertically...have corrected my ugliness $\endgroup$ – ubpdqn Nov 7 '14 at 12:06
  • 1
    $\begingroup$ I used graphics because i was not aware of Piecewise and other things you did.I should learn more thing in mathematica .great job.thanks $\endgroup$ – user2838619 Nov 7 '14 at 12:15
  • $\begingroup$ @ubpdqn, I wouldn't worry about it. Ugly code that works is still code that works :-) $\endgroup$ – Simon Woods Nov 7 '14 at 13:18
  • $\begingroup$ what's a good algorithm for this if I want to implement what Fit does in my own C/C++ code ? How to create a curve from a discrete set of points ? $\endgroup$ – user2485710 Nov 7 '14 at 17:02
  • $\begingroup$ @user2485710, Fit does least-squares fitting. There will be plenty of curve fitting libraries for C if you google it. For this specific case it's overkill in fact, because there is an exact solution for the quadratic passing through 3 points. I just used Fit because it's quick and easy to do it that way in Mathematica. $\endgroup$ – Simon Woods Nov 7 '14 at 17:21
5
$\begingroup$

EDITED (removal of uglier approach)

Here is an approach but it is a little slow:

 ac[x_] := 
 Total[Boole[#2] #1 & @@@ {{0, 0 < x < 2}, {-2, 2 < x < 6}, {6, 
     6 < x < 10}, {-2, 10 < x < 22}, {0, x > 22}}]
v[w_] := 3 + Integrate[ac[w], w]
d[w_] := Integrate[v[w], w]
p1 = Plot[ac[t], {t, 0, 25}, ExclusionsStyle -> Dashed, 
  PlotRange -> All]
p2 = Plot[Evaluate[v[t]], {t, 0, 25}, PlotRange -> All, 
  GridLines -> {{2, 6, 10, 22}, None}, GridLinesStyle -> Dashed]
p3 = Plot[Evaluate[d[t]], {t, 0, 25}, PlotRange -> All, 
  Exclusions -> None, GridLines -> {{2, 6, 10, 22}, None}, 
  GridLinesStyle -> Dashed]

enter image description here

$\endgroup$
2
$\begingroup$

I want to know that how can I write a function that draws parabola given by 3 point(parabola minimum or maximum point,and two other which parabola start and ends between them)?

Here is a B-spline approach, which I used in this previous answer:

parabolicArc[pts_?MatrixQ] /; Dimensions[pts] == {3, 2} := 
           BSplineCurve[ReplacePart[pts, 2 -> Mean[Delete[pts, 2]] +
           {0, (Subtract @@ pts[[{-1, 1}, 1]]) (Subtract @@ Divide @@@ Reverse /@
           Differences[pts])/2}], SplineDegree -> 2]

Here's Simon's example:

With[{pts = {{10, 10}, {30, 50}, {60, 20}}}, 
     Graphics[{PointSize[Large], Point[pts], Red, parabolicArc[pts]}, 
              PlotRange -> {10, 55}]]

a parabolic arc


As for solving the OP's actual problem, here's another approach:

acc = Interpolation[{{0, 0}, {2, 0}, {6, -2}, {10, 6}, {22, -2}, {24, 0}},
                    InterpolationOrder -> 0];

pos = NDSolveValue[{p''[t] == acc[t], p[0] == 0, p'[0] == 3}, p, {t, 0, 24}];
vel = pos';

Table[Plot[f[t], {t, 0, 24}, PlotRange -> All],
      {f, {acc, vel, pos}}] // GraphicsRow

acceleration, velocity, and position

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.