19
$\begingroup$

I'm trying to illustrate the solutions to a textbook problem dealing with quadratic functions.

This will involve plotting a quadratic and overlaying the plot and the image.

Here is the textbook scan.....enter image description here

The idea of the problem is to find several possible quadratic models that would go through the hoop.

I imported this image into a variable, call it img1

I wanted to establish a "baseline" so I started with a simple plot, x intercepts of 0 and 18, and vertex at (9,14). I know, NOT a solution to the problem but I wanted to see how the plot and image would match up.

I created the plot

g2 = Plot[-14/81 x (x - 18), {x, -1, 19}, PlotStyle -> Thick]

Then I put them together and tweaked the placement of the plot based on the image size.

ImageCompose[img1, g2, {983/2, 811/2}]

Which gives me this...

enter image description here

The vertex is in the right place, but the axes don't line up.

Sorry if this is a dumb question, I'm not at all sure how I could get my plot to match the background image so the axes in the image would be the same as the axes in my plot....

Do I need to scale my plot, or scale my image.. or something obvious that I am missing.

Any help is appreciated

$\endgroup$
3
  • $\begingroup$ If you right click a graphic or an image, there's a tool to "get coordinates". You can click on a number of points, then use Control-C to copy the coordinates. This can be helpful for aligning the image coordinate system with Plot's coordinate system. Alternatively, instead of using an image with a grid on it, could use only an image of a boy with a basketball, and place that image on the plot using the Epilog option. You could also place a basket :-) $\endgroup$
    – Szabolcs
    Apr 9, 2013 at 15:11
  • $\begingroup$ @Szabolcs I just read your comment after I did exactly that for my answer. :) $\endgroup$
    – einbandi
    Apr 9, 2013 at 15:26
  • $\begingroup$ The answers with Manipulate reminded me of this question: Animate ParametricPlot3D for two different parametric equations $\endgroup$
    – Jens
    Apr 9, 2013 at 18:38

3 Answers 3

18
$\begingroup$

Try this:

(* clip white borders *)
img = ImageCrop[Import["https://i.stack.imgur.com/La8Zs.jpg"]];

Plot[-14/81 x (x - 18), {x, -2, 19},
     PlotRange -> {-2, 16}, PlotStyle -> Directive[Red, Thick, Dashed], 
     Prolog -> {Texture[img],
                Polygon[{Scaled[{0, 0}], Scaled[{1, 0}], Scaled[{1, 1}], Scaled[{0, 1}]},
                        VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]},
     Ticks -> None]

plot with custom background

Notes:

  • If you want to fit in an image as background, you will often want to trim margins; ImageCrop[] is a good function for the purpose.

  • Luckily, your background image has its own coordinate system; you can then adjust PlotRange appropriately.

  • Prolog is most useful for putting primitives in the background.

  • Scaled[] ensures that the background textured polygon is scaled appropriately with respect to the plot range.

$\endgroup$
4
  • $\begingroup$ Thanks so much, that helps a TON. I'll be using this question in just a few hours, so I can get it to work NOW, and think about some of the ideas you mentioned. I really appreciate the help! $\endgroup$ Apr 9, 2013 at 15:01
  • $\begingroup$ Such a superior answer. It. Hurts. Me. :) $\endgroup$
    – BoLe
    Apr 9, 2013 at 17:53
  • 1
    $\begingroup$ I know we shouldn't write comments like "Thanks!" and so on, but thanks. That has just saved me probably a week of work and workarounds. $\endgroup$
    – yohbs
    May 13, 2013 at 15:24
  • $\begingroup$ @yohbs, you're welcome! I'm glad my attempt saved you some effort. :) $\endgroup$ May 13, 2013 at 15:25
11
$\begingroup$

EDIT: (see below for old version)

New version with alpha channels, the option to lock the graph at the ball, adjustable player position and a button to remove player and basket:

setalpha[im_] := 
 Module[{mask = 
    ChanVeseBinarize[im, TargetColor -> {1., 1., 1.}, 
     "LengthPenalty" -> 10]},
  mask = Blur[Erosion[ColorNegate[mask], 2], 5];
  Rasterize[SetAlphaChannel[im, mask], Background -> None]]

basket = setalpha[
   Import["http://www.hdwallpaperspk.com/wp-content/uploads/2013/02/ basketball_clipart.jpg"]];
guy = setalpha[
   Import["http://www.tu-chemnitz.de/ifm/produkte-medien/basketball_200.png"]];

Manipulate[
 Plot[If[locked, (-c - b pos[[1]] + pos[[2]])/pos[[1]]^2, a] x^2 + 
   b x + c, {x, 0, 16}, PlotRange -> {{0, 17}, {0, 14}},
  Frame -> True,
  ImageSize -> 500,
  BaseStyle -> {20, FontFamily -> "Helvetica"},
  FrameLabel -> {"Distance from Back of hoop (ft)", "Heigth (ft)"},
  GridLines -> {Range@16, Range@14},
  Prolog -> {Inset[If[show, basket, ""], {0.5, 8}, Top, 1], 
    Inset[If[show, guy, ""], pos, Top, 2.5]}],
 Item@Row[{"a  ", 
    Dynamic@Slider[Dynamic@a, {1, 10}, Enabled -> ! locked]}], 
 Item@Row[{"b  ", Dynamic@Slider[Dynamic@b, {1, 10}]}],
 Item@Row[{"c  ", Dynamic@Slider[Dynamic@c, {1, 10}]}],
 {{pos, {16, 6}}, Locator},
 {{locked, True, "Lock graph at ball"}, {True, False}},
 {{show, True, "Show player and basket"}, {True, False}},
 ControlPlacement -> Left]

enter image description here


Old version:

Alternatively, you can also create the whole thing completely in Mathematica. I also added Manipulate for fun:

basket = Import[
        "http://www.hdwallpaperspk.com/wp-content/uploads/2013/02/basketball_clipart.jpg"];
guy = Import["http://www.tu-chemnitz.de/ifm/produkte-medien/basketball_200.png"];

Manipulate[
 Plot[-(c x - b)^2 + a, {x, 0, 16},
  PlotRange -> {{0, 17}, {0, 14}},
  Frame -> True,
  ImageSize -> 500,
  BaseStyle -> {20, FontFamily -> "Helvetica"},
  FrameLabel -> {"Distance from Back of hoop (ft)", "Heigth (ft)"},
  GridLines -> {Range@16, Range@14},
  Prolog -> {Inset[basket, {0.5, 8}, Top, 1],
    Inset[guy, {16, 6}, Top, 2.5]}],
 {a, 8, 20}, {b, 1, 10}, {c, 0.1, 1}]
$\endgroup$
3
  • $\begingroup$ Wow! Looks fantastic, I'll check that out later today when I have time. This is nice since I could have buttons to show the "guy" and "hoop", take them off once the student gets into the problem. Really nice. I really appreciate seeing solutions like this since I can really connect to the commands being used since they apply directly to my problem. Thanks for your time! $\endgroup$ Apr 9, 2013 at 15:47
  • 4
    $\begingroup$ Now the player only needs a tad alpha channel to remove the white background $\endgroup$
    – Yves Klett
    Apr 9, 2013 at 16:01
  • $\begingroup$ @YvesKlett the new version comes with alpha channels. Thanks for the link, btw. It's really useful! :) $\endgroup$
    – einbandi
    Apr 9, 2013 at 18:01
5
$\begingroup$

I enlarge the image canvas if throw flies outside.

together[i, {4, 22, 10}]

Throw 1

Parabola with zeroes x1, x2 and vertex at {(x1 + x2)/2, y3}:

y[{x1_, x2_, y3_}, x_] := -4 (x - x1) (x - x2) y3/(x1 - x2)^2

i = ImageCrop@Import@"https://i.stack.imgur.com/La8Zs.jpg";

Note ImageCrop, it ensured me constant ImageDimensions[i]/{21, 18} pixels for each unit.

together[i_Image, {x1_, x2_, y3_}] :=
 Module[{p, r, u, v},
  {u, v} = ImageDimensions@i/{21., 18.};
  p = Plot[y[{x1, x2, y3}, x], {x, x1, x2},
    PlotRange -> {{x1, x2}, {0, y3}},
    AspectRatio -> Automatic,
    PlotRangePadding -> 0, ImagePadding -> 0, Axes -> None,
    PlotStyle -> Directive[Red, AbsoluteThickness[3]]];
  r = PlotRange /. AbsoluteOptions[p, PlotRange];
  p = Image[p, ImageSize -> u Abs[Subtract @@ First[r]]];
  p = SetAlphaChannel[p, Dilation[ColorNegate@Binarize@p, 1]];
  With[{pl = Max[0, -1 - x1]},
   ImageCompose[ImagePad[i, {
      Round[u {pl, Max[0, x2 - 18]}],
      Round[v {0, Max[0, y3 - 15]}]}, White], p,
    {u (2 + pl + r[[1, 1]]), 2 v}, {0, 0}]]]

together[i, {0, 18, 14}]

throw2

$\endgroup$
1
  • $\begingroup$ This is really helpful, since it shows a lot of nice ways to massage the imported image, as well as the function to create a quadratic from zeroes and the y value of the vertex. Things like that are very helpful and I don't often think of doing that. $\endgroup$ Apr 11, 2013 at 20:30

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.