I had not yet discovered tutorial/AdvancedManipulateFunctionality, and
having worked through that tutorial I see now how to use Manipulate much
more effectively.
I have also worked through your examples, but I find the interactive
graphics performance on my PC is very poor for those examples that you say
you can run acceptably fast. I have a 2.1GHz PC with 2.5GB RM, so I assume
it is my graphics card that is the limiting factor for me; it is an ATI
Radeon 9600 which is fairly low in the graphics card pecking order these
days.
I think the important criteria for me are continuously updated interactive
manipulation of graphics, where the part of the graphics that is changing in
response to the controller movements can be rendered at a lower resolution.
This is the effect that I was (clumsily) trying to achieve in my example
code.
Anyway, based on my experiments and your suggestions I have convinced myself
that this sort of graphics manipulation is indeed possible in Mathematica 6,
but you have to be careful to ensure that no more graphics
computation/rendering is done than is necessary.
Steve Luttrell
West Malvern, UK
"John Fultz" <jfultz at wolfram.com> wrote in message
news:f4tkii$hp2$1 at smc.vnet.net...
> Yes, your post brings up some important points about Manipulate which I'd
> like
> to address.
>
> First, it's actually pretty uncommon that the speed of a Manipulate is
> affected
> by rendering time. It can happen, but it's much more likely that the
> reason for
> a Manipulate to slow down is because of computational time...i.e. it's
> doing theentire computation over again. But whatever the cause, there's a
> lot you can doinside of Manipulate to affect the results. Some
> illustrations...
>
> Manipulate[
> Show[Plot3D[Sin[x y], {x, 0, 5}, {y, 0, 5}, Filling -> Bottom,
> PlotPoints -> 30],
> Graphics3D[{PointSize[.1], Point[Append[xy, 1]]}]], {xy, {0, 0}, {5,
> 5}}]
>
> I've added the PlotPoints here to demonstrate the computational cost, and
> Filling to add rendering cost (you may remember a previous post where I
> indicated that adding transparency to a 3D graphic, as the default
> FillingStyle
> does, significantly increases rendering complexity).
>
> The 2D slider in this example does nothing more than move the point
> around.
> But, in fact, whenever you're moving the slider, it's recomputing the
> entire
> Show[] expression, including redoing the Plot3D from scratch every time.
> However, while you're moving the slider, the quality of the resulting
> graphic
> is lower, which significantly reduces both computational and rendering
> complexity.
> This is because Manipulate is making a speed/quality tradeoff by applying
> the
> option PerformanceGoal to Plot3D. We can manually override this by
> providing
> our own PerformanceGoal option to see how much better things look, and how
> much
> worse performance is...
>
> Manipulate[
> Show[Plot3D[Sin[x y], {x, 0, 5}, {y, 0, 5}, Filling -> Bottom,
> PlotPoints -> 30, PerformanceGoal -> "Quality"],
> Graphics3D[{PointSize[.1], Point[Append[xy, 1]]}]], {xy, {0, 0}, {5,
> 5}}]
>
>
> This looks wonderful, but the responsiveness is horrible. We're now
> getting the
> full computational+rendering cost of the Plot3D every time we move the
> point.
> We can do better. Since we know that the Plot3D is essentially a static
> element, we can direct Manipulate to only change the dynamic elements. We
> do
> this by embedding Dynamic around the elements we want to be considered
> independently. In this case, the only dynamic element is the coordinate
> of the
> Point (the fact that there is a point is static; only it's location is
> Dynamic).
> So, let's tweak the above by wrapping the Append in Dynamic...
>
> Manipulate[
> Show[Plot3D[Sin[x y], {x, 0, 5}, {y, 0, 5}, Filling -> Bottom,
> PlotPoints -> 30, PerformanceGoal -> "Quality"],
> Graphics3D[{PointSize[.1],
> Point[Dynamic[Append[xy, 1]]]}]], {xy, {0, 0}, {5, 5}}]
>
>
> This is more responsive, but still pretty bad. We're dealing here with
> less
> time spent in the kernel and more time in the FE rebuilding the BSP tree
> and
> using slower rendering methods because of the transparency. Another
> stratagem
> to speed things up is to use the ControlActive function to change how
> things arebeing evaluated and/or rendered during the manipulation of a
> control. So, in
> this case, we could use ControlActive to remove the Filling during the
> drag...
>
> Manipulate[
> Show[Plot3D[Sin[x y], {x, 0, 5}, {y, 0, 5},
> Filling -> ControlActive[xy; None, Bottom], PlotPoints -> 30,
> PerformanceGoal -> "Quality"],
> Graphics3D[{PointSize[.1],
> Point[Dynamic[Append[xy, 1]]]}]], {xy, {0, 0}, {5, 5}}]
>
> Note that we had to make the ControlActive[] dependent upon the xy
> variable;
> since Filling didn't have a natural dependency on xy, I added it to a
> CompoundExpression. This, you'll find, is a good tradeoff of
> responsiveness and
> consistent quality. There's a bit of a delay when you start and stop
> moving the
> control, but while you're moving it, the responsiveness is reasonable.
>
> Finally, if you're willing to give up interactive updating, you could set
> ContinuousAction->False on the Manipulate.
>
> Steve, you're absolutely right that sometimes you have to construct your
> own
> Dynamic expressions and controls for maximum flexibility and performance.
> However, there's quite a lot which can be done with Manipulate, as well.
>
> For more information on improving the performance of Manipulate, make sure
> to
> check out the Manipulate tutorials...
>
> tutorial/IntroductionToManipulate
> tutorial/AdvancedManipulateFunctionality
>
> Sincerely,
>
> John Fultz
> jfultz at wolfram.com
> User Interface Group
> Wolfram Research, Inc.
>
>
>
> On Mon, 11 Jun 2007 04:17:02 -0400 (EDT), Steve Luttrell wrote:
>> I have been experimenting to try to find a way of answering my own
>> question.
>>
>> It seems that part of the problem was that using Manipulate introduuces
>> some
>> overheads that can be avoided by writing your own interactive graphics
>> code.
>>
>> The code below is the result of some experimentation that shows a useful
>> level of interactive manipulation of a 2-dimensional manifold.
>>
>> Define a cut-out region. This is a "window" within which the manifold is
>> being interactively manipulated.
>>
>> cutout[\[Phi]_, \[Theta]_] := (9 \[Pi])/8 < \[Phi] < (13 \[Pi])/
>> 8 && \[Pi]/4 < \[Theta] < (3 \[Pi])/4;
>>
>> Basic spherical region with a cut-out. This is a background graphic
>> showing
>> everything except the part that is being manipulated.
>>
>> g0 = ParametricPlot3D[{Sin[\[Theta]] Cos[\[Phi]],
>> Sin[\[Theta]] Sin[\[Phi]], Cos[\[Theta]]}, {\[Phi], 0,
>> 2 \[Pi]}, {\[Theta], 0, \[Pi]},
>> RegionFunction -> (Not[cutout[#4, #5]] &)];
>>
>> Define a fiducial point. This is the location of the tip of a "nose"-like
>> protrusion that is being manipulated around the manifold.
>>
>> {\[Phi]1, \[Theta]1} = {(11 \[Pi])/8, \[Pi]/2};
>> Slider2D[Dynamic[{\[Phi]1, \[Theta]1}], {{0, \[Pi]}, {2 \[Pi], 0}}]
>>
>> Dynamically updated display of everything.
>>
>> Dynamic[
>> u = (1 +
>> 0.5 Exp[-((\[Theta] - \[Theta]1)/0.25)^2 - ((\[Phi] - \[Phi]1)/
>> 0.25)^2]) {Sin[\[Theta]] Cos[\[Phi]],
>> Sin[\[Theta]] Sin[\[Phi]], Cos[\[Theta]]};
>> p = 1.01 u /. {\[Theta] -> \[Theta]1, \[Phi] -> \[Phi]1};
>> g1 = ParametricPlot3D[u, {\[Phi], 0, 2 \[Pi]}, {\[Theta], 0, \[Pi]},
>> RegionFunction -> (cutout[#4, #5] &)];
>> g2 = Graphics3D[{Red, PointSize[0.05], Point[p]}];
>> Show[g0, g1, g2, PlotRange -> 2 {{-1, 1}, {-1, 1}, {-1, 1}},
>> AxesLabel -> {"x", "y", "z"}]
>> ]
>>
>> Now you can move the 2D slider around (slowly!) to adjust the position of
>> the "nose" on the sphere. On my version of Mathematica (Windows XP
>> 32-bit)
>> as you move the slider you get a continuously updated fiducial point and
>> "nose", but the mesh on the nose doesn't get drawn in until you release
>> the
>> mouse button. Also the border of the "nose" is not drawn in during the
>> continuous updates.
>>
>> This code produces results that are a LOT better than the situation was
>> when
>> I wrote my original posting, and this approach may be a worthwhile
>> starting
>> point for this type of interactive manipulation.
>>
>> Steve Luttrell
>> West Malvern, UK
>>
>> "Steve Luttrell" <steve at _removemefirst_luttrell.org.uk> wrote in message
>> news:f4gmui$hpj$1 at smc.vnet.net...
>>> In version 6 I want to do interactive graphics where I use a controller
>>> to
>>> manipulate the shape of a curved 2-dimensional manifold (for instance).
>>> This
>>> is a type of interaction with Mathematica that should be of interest to
>>> lots
>>> of people.
>>>
>>> The main problem that I have is that the redraw time after each
>>> controller
>>> movement is quite long. I need continuous feedback so that I can
>>> immediately
>>> see the effect of making various controller movements, so using
>>> ContinuousAction->False in Manipulate (for instance) doesn't solve this
>>> problem. I have tried various shortcuts such as skeletonising the
>>> graphic
>>> during updates so that it redraws quicker, but it is still too slow, and
>>> will get worse for the more complicated graphics that I really want to
>>> work
>>> on.
>>>
>>> As a general solution it would be great if it was possible to control
>>> the
>>> redrawing of graphics so that only those parts that need to be redrawn
>>> are
>>> actually redrawn, with the user taking responsibility for any
>>> consequential
>>> errors in the accumulated graphics rendering. Here I don't want to
>>> simply
>>> zoom the graphic to limit the rendered region, because I want to
>>> interactively see the impact of my manipulations in the context of the
>>> whole
>>> graphic.
>>>
>>> Does anyone know a way of imposing this type of control (see above) on
>>> graphics rendering, or is it not actually possible in Mathematica? I
>>> think
>>> the answer is no, but I just want to make sure that I haven't
>>> overlooked a
>>> trick here.
>>>
>>> Steve Luttrell
>>> West Malvern, UK
>
>
>