# draw part of parabola using graphics

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: 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: 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).

• Why are you doing all this with Graphics instead of just using Plot? Seems you are making this harder than it has to be. – Jason B. Nov 7 '14 at 10:15
• You may also want to consider integrating the acceleration two times to get s(t). – Yves Klett Nov 7 '14 at 10:18
• @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. – user2838619 Nov 7 '14 at 10:21
• @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. – user2838619 Nov 7 '14 at 10:26
• 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. – Yves Klett Nov 7 '14 at 10:37

## 3 Answers

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]}] 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}] • @SimonWoods...I feel somewhat ashamed of the ugliness of my code...though I like aligning vertically...have corrected my ugliness – ubpdqn Nov 7 '14 at 12:06
• 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 – user2838619 Nov 7 '14 at 12:15
• @ubpdqn, I wouldn't worry about it. Ugly code that works is still code that works :-) – Simon Woods Nov 7 '14 at 13:18
• 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 ? – user2485710 Nov 7 '14 at 17:02
• @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. – Simon Woods Nov 7 '14 at 17:21

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] 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}]] 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, p' == 3}, p, {t, 0, 24}];
vel = pos';

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