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.