MathGroup Archive 2006

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

Search the Archive

Re: 3D plot with range restricted to non-rectangular region

  • To: mathgroup at smc.vnet.net
  • Subject: [mg66144] Re: [mg66097] 3D plot with range restricted to non-rectangular region
  • From: "David Park" <djmp at earthlink.net>
  • Date: Sun, 30 Apr 2006 04:22:22 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

David,

With regular Mathematica you can make a decent, but slightly ragged plot.

h[x_, y_, z_] := Log[x] + Log[y] + Log[z]
h2[x_, y_] := h[x, y, 1 - x - y]

domain[x_, y_] := 0 < x < 1 && 0 < y < 1 - x

Plot3D[If[domain[x, y], h2[x, y], -10], {x, 0, 1}, {y, 0, 1},
    ViewPoint -> {2.912, -0.979, 1.418},
    ImageSize -> 500];

The only problem with that is that the plot is ragged along the diagonal
edge and we are forced to plot some value for the region outside the domain
and we might prefer no plot there at all.

There is also a general problem with a plot of this function in that it goes
to -Infinity at the edges of the domain. We will either want to restrict the
PlotRange or restrict the domain slightly to eliminate the steep vertical
walls.

If you want to use the DrawGraphics Mathematica package from my web site
then there are two other methods to obtain a smoother plot.

Needs["DrawGraphics`DrawingMaster`"]

Needs["Graphics`Animation`"]

The first method is to use the IteratorSubstitution routine that will
reparametrize the function, replacing y by a new variable w that has a fixed
iterator range. I am going to use a ParametricPlot3D so I feed the
parametrization of the surface and the y domain into the routine. We get out
the new parametrization and w iterator.

IteratorSubstitution[{x, y, h2[x, y]}, {y, 0, 1 - x}]
{{x, w - w x, Log[(-1 + w) (-1 + x)] + Log[x] + Log[w - w x]}, {w, 0, 1}}

You can then use this in the ParametricPlot3D command. You can evaluate the
following two commands even without DrawGraphics. Notice that I slightly
restricted the plot domain to eliminate the steep walls.

plot1 =
    ParametricPlot3D[{x, w - w x,
        Log[(-1 + w) (-1 + x)] + Log[x] + Log[w - w x]}, {x, 0.01, 0.99},
{w,
        0.01, 0.99},
      BoxRatios -> {1, 1, 1/2},
      ViewPoint -> {2.912, -0.979, 1.418},
      ImageSize -> 500];

You can obtain a more complete view by spinning it around and using the
up/down arrow keys to advance one frame at a time. The domain and edges are
now completely smooth.

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

The second method, and for this you will actually need DrawGraphics, is to
make a grid of polygons and then trim them to your actual domain. Again I
slightly restrict the domain.

domain[x_, y_] := 0.01 <= x <= 0.99 && 0.01 <= y <= 0.99 - x

The following makes a 40 x 40 grid of squares that covers the basic domain.

polygrid = MakePolyGrid[{40, 40}, {{0, 0}, {1, 1}}] // N;

The following then trims the polygons to fit the domain.

polys = polygrid // TrimPolygonsBoole[domain];

The following plots the resulting grid in the xy-plane.

Draw2D[
    {Burlywood, polys,
      polys // PolygonOutline[Black]},
    AspectRatio -> Automatic,
    Frame -> True,
    ImageSize -> 300];

and the following raises the polygonal grid to a 3D surface with smooth
edges.

plot2 =
    Draw3DItems[
      {SurfaceColor[Burlywood], EdgeForm[ColorMix[Burlywood, Black][0.3]],
        polys // RaiseTo3D[h2]},
      NeutralLighting[0.3, 0.5, 0.1, -5°],
      BoxStyle -> Gray,
      BoxRatios -> {1, 1, 0.7},
      ViewPoint -> {2.912, -0.979, 1.418},
      Background -> LightBlue,
      ImageSize -> 500];

In this case I colored the surface and gave it a subdued "mesh". You could
SpinShow it just like the other plot.

The difference between the two plots is that in the first case the "mesh"
lines follow the triangular shape of the domain, but in the second case the
"mesh" is square but trimmed to the edges of the domain.

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

From: David Sanders [mailto:dpsanders at gmail.com]
To: mathgroup at smc.vnet.net


Hi,

I want to plot a function whose range is naturally restricted to a
non-rectangular region:

h[x_, y_, z_] := Log[x] + Log[y] + Log[z]

h2[x_, y_] := h[x, y, 1 - x - y]

Only the region {(x,y): 0<x<1; 0<y<1-x}  is allowed.

If I try the naive
Plot3D[h2[x, y], {x, 0, 1}, {y, 0, 1}]

then I get error messages of the type:

Plot3D::plnc: h2[x, y] is neither a machine-size real number at {x,
y}={0.5, \
0.5} nor a list of a real number and a valid color directive

But then it plots the graph anyway.

I also need contour plots of functions like this.

Is there a proper way of avoiding these error messages, like making it
ignore points whenever they contain an illegal operation (here, Log of
a negative number)?

Thanks,
David.



  • Prev by Date: Re: "In progress" saving of data collected using Reap/Sow
  • Next by Date: Re: Re: Illusory Multicore Support in 5.2?
  • Previous by thread: Re: 3D plot with range restricted to non-rectangular region
  • Next by thread: Testing for a non-constant variance