Date: Jan 18, 2013 12:50 AM
Author: Brentt
Subject: Eternal Trouble with Dynamic: fishing for tips on my coding process?


Hi, everytime I think I have Dynamic down it seemingly inexplicably breaks.
I'd much appreciate if I could step through the process that leaves me with
code that, with one small change, just stops working. (Maybe some designers
might get something out of seeing the coding process of an idiot?)

So I want to draw a set of points on a graphic and then show a dynamically
updated interpolating function for those points. This is my interpolating
function, having this dynamically update upon drawing a set of points in
the graphic is the goal:


parametricInterpolation[param_, pointList_] :=
> Function[{t},
> Function[{f}, f[t]] /@
> Quiet[(ListInterpolation /@ Transpose[pointList])]][param];
>


The function works if I take a random set of points. So I set it aside to
get the dynamic interface working using a more simple function in its place
(just so I know if any problems arise, which they have, it has nothing
within the above slightly complicated function. )

Ok, so here is where I start. The point set are to be drawn when the mouse
is dragged on the graphic. To keep the code as simple as possible I start
with a point at the origin:

DynamicModule[
> {r = {{0, 0}}, interpol = {}},
>
> interpol =
> Dynamic@If[Length[r] >= 3, Circle[Last[r], 1/Length[r]], {}];
> EventHandler[
> Show[
> {
> Graphics[{Line[Dynamic[r]]}],
> Graphics[{interpol}]
> },
> PlotRange -> ( {
> {-1, 1},
> {-1, 1}
> } )
> ],
> {"MouseDragged" :> (r =
> DeleteCases[AppendTo[r, MousePosition["Graphics"]], None])}]
> ]
>



The variable interpol is going to eventually hold my interpolating
function. Since it needs at least 3 points to work properly, I have the
conditional so it need not evaluate until at least 3 points are drawn. The
Circle[Last[r], 1/Length[r]] I'm using as a test function in the
interpolating function's place. (it simply draws a circle which shrinks as
function of the the number of points).

Code works so far. But the problem is I need the interpolating function to
be plotted using ParametricPlot. I need to replace Graphics[{Interpol}]
with a ParametricPlot.

Now this seems like it should be a rather simple step. But alas, no such
luck. My apparently naive approach is to have interpol hold a graphics
object, and then use that as an element in Show's list argument. This way,
if it would work for the simpler function which draws the shrinking circle,
it would just be a matter of replacing this with a ParametricPlot which
plots my interpolation function. But the code breaks before I even get
there. Here is the seemingly small step that breaks the code

DynamicModule[
> {r = {{0, 0}}, interpol = {}},
>
> interpol =
> Dynamic@If[Length[r] >= 3, Graphics[{Circle[Last[r], 1/Length[r]]}],
> Graphics[{}]];
> EventHandler[
> Show[
> {
> Graphics[{Line[Dynamic[r]]}],
> interpol
> },
> PlotRange -> ( {
> {-1, 1},
> {-1, 1}
> } )
> ],
> {"MouseDragged" :> (r =
> DeleteCases[AppendTo[r, MousePosition["Graphics"]], None])}]
> ]
>



With the result

Show::gcomb: Could not combine the graphics objects in Show[{\!\(\*
GraphicsBox[LineBox[Dynamic[r$4494]]]\),\!\(\*
GraphicsBox[{}]\)},PlotRange->{{-1,1},{-1,1}}]. >>


I'm not sure what to make of the error message. It seems like what I did
should work. I'm just passing a graphics object instead of an argument for
Graphics and I'm not sure why should that be a problem? Is there something
about Graphics that behaves differently that other functions I suppose, but
I haven't been able to discern what that is. Any tips would be greatly
appreciated (whether it is about this code in particular, or anything about
the process. And please forgive me if I seem thick, I'm an undergraduate
mathematics major, but not a terribly good one. This isn't for school work,
I'm just trying to figure out Mathematica to explore ideas I've learned
about. I feel like I have a good sense of how it works except when it comes
to this Dynamic functionality.)