7
$\begingroup$

I would like to have two Graphics objects displayed side by side such that:

  • they are mirror images of each other
  • if I change the left-hand one interactively using Drawing Tools, the other one is updated automatically.

I can't seem to convince Dynamic, Manipulate and friends to do this for me. How can I do it?

A more basic question would be: how do I create a variable which holds a Graphics object and such that its value can be changed interactively using Drawing Tools?

$\endgroup$
9
  • $\begingroup$ Assuming you mean Graphics not Graph ... is Combining manipulated plots of any help? $\endgroup$
    – user9660
    Commented Aug 13, 2014 at 16:07
  • $\begingroup$ Did I write "Graph" anywhere by accident? $\endgroup$ Commented Aug 13, 2014 at 16:12
  • $\begingroup$ No, that question just asks how to have to dynamic Graphics objects next to each other. I want one of them to reflect the content of the other, dynamically, so that if I edit interactively the one, the other changes. $\endgroup$ Commented Aug 13, 2014 at 16:14
  • $\begingroup$ I was pointing to the second answer, good luck. $\endgroup$
    – user9660
    Commented Aug 13, 2014 at 16:19
  • 2
    $\begingroup$ I think it is likely that this is impossible. Variables get their values from the kernel, but Drawing Tools works entirely in the front end. There isn't any variable that holds the updates that you do to the image. $\endgroup$
    – C. E.
    Commented Aug 14, 2014 at 2:40

3 Answers 3

5
$\begingroup$

This solution may generate a storm of criticisms but may also give you an idea of a path to follow to get where you want. Note that this solution works perfectly in Mathematica 9 but in Mathematica 10 there is a problem that is preventing the last Graphics object added to copy to the right side with the right colors.

    g = Graphics[{Yellow, Disk[]}, ImageSize -> 200];
rightSide = Style["Left side will be copied here.", Gray, Italic];
Deploy@Panel@
  Grid[{{
     Labeled[Button["Copy to Right Side",
       Block[{cellContents = NotebookRead[EvaluationCell[]], rs},
        rs = 
         cellContents[[Sequence @@ 
             Position[cellContents, GridBox[{{_, _}}, ___]][[2]]]][[1,
            1, 1, 1, 2]];
        rightSide = 
         ReplaceAll[DisplayForm@rs, GraphicsBox -> Graphics];
        ]
       , ImageSize -> Automatic
       ], Style[g, Deployed -> False]]
     ,
     Labeled[
      "Copy of Left Side"
      , Dynamic@rightSide
      ]
     }}
   , Alignment -> Left
   ]

This is how it looks after the first evaluation:

enter image description here

And this is how it looks after adding two Graphics elements and pressing the "Copy to Right Side" button.

enter image description here

$\endgroup$
1
$\begingroup$

Another apporach is to make a Manipulate that does what you want. For example, here is one that draws a polygon. Whenever you move the points of the left polygon, the one on the right moves in mirror symmetry.

Manipulate[Graphics[{Polygon[p], Red, Polygon[ConstantArray[{10, 0}, 4] - p]}], 
   {{p, {{1, 1}, {2, 2}, {-1, 1}, {-2, -2}}}, Locator}]

enter image description here

enter image description here

$\endgroup$
3
  • $\begingroup$ The main point is that the solution works when Drawing Tools is used. $\endgroup$ Commented Aug 25, 2014 at 1:24
  • 1
    $\begingroup$ Well, I read the OPs comment "If I have to give up on the Drawing tools then I could at least make a simple drawing canvas. That would work" and thought an alternative approach (ie., a "simple drawing canvas") might be useful. $\endgroup$
    – bill s
    Commented Aug 25, 2014 at 1:26
  • $\begingroup$ How could I do this but have two Graphics objects, so the shapes can't get mixed up? If I place the red object into another Graphics and then combine them with Grid, I think the locators are screwed up (they are relative to the entire grid, not just the left-hand Graphics). $\endgroup$ Commented Aug 25, 2014 at 6:24
0
$\begingroup$

Well, despite Drawing tools only works in FrontEnd, you can always get the CellExpression directly:

Grid[{
        {"draw here:", "watch it here:"},
        {Graphics[],
            Dynamic[Refresh[
                    Cases[
                                NotebookRead[
                                    EvaluationCell[]], _GraphicsBox, ∞][[1]] // 
                        RawBoxes,
                    UpdateInterval -> 0]]
            }
        }, Frame -> All]
$\endgroup$

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.