MathGroup Archive 2004

[Date Index] [Thread Index] [Author Index]

Search the Archive

RE: How to set y always greater than or equal to x for a function?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg46591] RE: [mg46569] How to set y always greater than or equal to x for a function?
  • From: "David Park" <djmp at earthlink.net>
  • Date: Tue, 24 Feb 2004 21:04:50 -0500 (EST)
  • Sender: owner-wri-mathgroup at wolfram.com

Albert,

I think this is an interesting plotting problem whose solution is not
totally obvious. If you are just beginning to learn Mathematica, then it is
probably not the first problem to tackle.

Plot3D[Sqrt[y - x], {x, -100, 100}, {y, -100, 100}];

gives warning messages and a jagged edge to the surface.

We could define a function

f[x_, y_] := If[y > x, Sqrt[y - x], 0]

Then

Plot3D[f[x, y], {x, -100, 100}, {y, -100, 100}];

works more or less. But it has the extra xy-plane surface, which is not part
of the surface you are specifying.

A few years ago I learned the following trick from MathGroup. (I can't
remember exactly who posted it.) Generate the plot above and then throw out
all points that have y <= x.

plot1 = Graphics3D@
      Plot3D[f[x, y], {x, -100, 100}, {y, -100, 100},
        DisplayFunction -> Identity];

plot2 = MapAt[# /. {x_?NumberQ, y_?NumberQ, z_?NumberQ} /; y <= x ->
            Sequence[] &, plot1, 1];

We had to convert the plot from SurfaceGraphics to Graphics3D. We had to map
our function onto the first part of plot1. The first part contains all the
primitive graphics for the surface. Any point in a Polygon for which y <=x
gets replaced by Sequence[], which effectly gets rid of it. We then Show the
new plot.

Show[plot2, DisplayFunction -> $DisplayFunction];

That gives a pretty good representation of the surface.

The DrawGraphics package at my web site gives some other techniques for
handling plotting problems of this type. One of its advantages is that it
automatically extracts the primitive graphics from any plot and it is then
easy to manipulate or combine the various elements.

Needs["DrawGraphics`DrawingMaster`"]

The following implements the same trick as above.

Module[{g},
    g = Draw3D[f[x, y], {x, -100, 100}, {y, -100, 100}];
    Draw3DItems[
      {g /. {x_?NumberQ, y_?NumberQ, z_?NumberQ} /; y <= x -> Sequence[]},
      BoxRatios -> {1, 1, 1/2},
      Axes -> True]];

Another method is to reparametrize the surface. If we were going to
integrate a two variable function we could use
Integrate[f[x,y],{x,-100,100},{y,x,100}]. The second iterator depends on x.
But we can't directly do that when plotting surfaces. DrawGraphics has the
command

IteratorSubstitution[{y, Sqrt[y - x]}, {y, x, 100}]
{{(-w)*(-100 + x) + x, Sqrt[(-w)*(-100 + x)]}, {w, 0, 1}}

It reparametrizes y and Sqrt[y-x] for {y,x,100} in terms of x and w. w has
the fixed iterator {w,0,1}. We can then plot this new function and then use
DrawingTransform3D to get back from the xw-plane to the xy-plane.

Draw3DItems[
{Draw3D[Sqrt[(-w)*(-100 + x)], {x, -100, 100}, {w, 0, 1}] /.
     DrawingTransform3D[#1 & , (-#2)*(-100 + #1) + #1 & , #3 & ]},

   BoxRatios -> {1, 1, 1/2},
   Axes -> True,
   Background -> Linen,
   ImageSize -> 450];

But this isn't too nice for this particular case because the polygons are
crimed together at one corner.

Another idea is to plot the function Sqrt[y], where we can use fixed ranges
and then rotate it by 45 degrees. I plot it in two sections to get a better
representation of the rising section.

Draw3DItems[
    {{Draw3D[Sqrt[y], {x, -150, 150}, {y, 0, 2}, PlotPoints -> {25, 2}],
          Draw3D[Sqrt[y], {x, -150, 150}, {y, 2, 150}, PlotPoints -> 25]} //
        UseRotateShape[-45°, 0, 0]},
    BoxRatios -> {1, 1, 1/2},
    PlotRange -> {{-100, 100}1.01, {-100, 100}1.01, {-0.1, 15.1}},
    Axes -> True,
    Background -> Linen,
    ImageSize -> 450];

This is probably a little nicer than the non DrawGraphics plot because the
"mesh" lines are either level, or the sqrt curves.

As an extra, here is the same surface combined with -Sqrt[y-x] and then spun
around for better viewing. g is just the primitive graphics for the surface
we plotted above. We draw it and then we draw it again with the z component
reversed.

plot3 =
    Module[{g},
      g = {Draw3D[Sqrt[y], {x, -150, 150}, {y, 0, 2}, PlotPoints -> {25,
2}],
            Draw3D[Sqrt[y], {x, -150, 150}, {y, 2, 150}, PlotPoints -> 25]}
//
           UseRotateShape[-45°, 0, 0];
      Draw3DItems[
        {g,
          g /. DrawingTransform3D[#1 &, #2 &, -#3 &]},
        BoxRatios -> {1, 1, 1},
        Boxed -> False,
        PlotRange -> {{-100, 100}1.01, {-100, 100}1.01, {-12.1, 12.1}},
        Background -> Linen,
        ViewPoint -> {1.779, -2.844, 0.447},
        ImageSize -> 450]];

SpinShow[plot3]
SelectionMove[EvaluationNotebook[], All, GeneratedCell]
FrontEndTokenExecute["OpenCloseGroup"]; Pause[0.5];
FrontEndExecute[{FrontEnd`SelectionAnimate[200, AnimationDisplayTime -> 0.1,
      AnimationDirection -> Forward]}]

David Park
djmp at earthlink.net
http://home.earthlink.net/~djmp/






From: Albert Franco [mailto:francoatnsuok at earthlink.net]
To: mathgroup at smc.vnet.net

I recently purchased Mathematica 5.0, and I am in the process of
learning how to take advantage of it's many features.

This is an example of one line I would like to calculate in Mathematica:

Plot3D[Sqrt[y-x],{x,-100,100},{y,-100,100}];


How can I best edit this line to make y always greater than or equal to x
during
calculation so the program doesn't try to take the square root of a
negative number?

Any help will be appreciated.

Albert Franco






  • Prev by Date: Reordering Downvalues?
  • Next by Date: Re: Bloomberg and Mathematica
  • Previous by thread: Re: How to set y always greater than or equal to x for a function?
  • Next by thread: Re: How to set y always greater than or equal to x for a function?