5

I'm wondering how to plot the boundaries of each piece of a bivariate piecewise function. Lets take for instance the following piecewise linear function $B_{111}(x,y)$:

B11[x_, y_] = Piecewise[{{1, 0 <= x <= 1 && 0 <= y <= 1}}]
B111[x_, y_] = Integrate[B11[x - t, y - t], {t, 0, 1}]

At the moment, I use the following Plot3D command to visualize the function:

Plot3D[B111[x, y], {x, -0.2, 2.2}, {y, -0.2, 2.2}, 
       PlotRange -> Full, PlotPoints -> 25, Axes -> False, 
       Boxed -> False, Mesh -> None]

enter image description here

Although in this particular case the boundaries of the individual pieces are already visible due to low quality plot settings, how can I actively plot these boundaries (i.e. as mesh or wireframe) in the same visualization?

Edit: In this case, it should result in a wireframe consisting of six triangles (and one hexagon):

enter image description here

Additionally, is it possible to add some kind of constraint to the Plot3D function, such that it only visualizes the actual function? In other words, it should exclude the parts where the function is not defined (i.e. outside the support assigned a grey color in the image below).

Kuba
  • 136,707
  • 13
  • 279
  • 740
Ailurus
  • 235
  • 1
  • 6

1 Answers1

6

Response to OP's last edit:

[...] is it possible to add some kind of constraint to the Plot3D function, such that it only visualizes the actual function? [...]

It is visualising actual function. From Piecewise documentation you will get that it is by default set to 0 to other arguments than matched True with conditions. You can set B11[x_, y_] = Piecewise[{{1, 0 <= x <= 1 && 0 <= y <= 1}},None]; but unfortunatell it will get dirty after differentiation.

Lets assume you do not want to know specific coordinates but only plot the wireframe you've described.

I'm going to put with force None to last part of B111. Then we will use BoundaryStyle and ExlusionsStyle to plot the wireframe ;)

 B11[x_, y_] = Piecewise[{{1, 0 <= x <= 1 && 0 <= y <= 1}}];
 B111[x_, y_] = Integrate[B11[x - t, y - t], {t, 0, 1}];

 f[x_, y_] = Piecewise[First[List @@ B111[x, y]], None]

 Plot3D[f[x, y], {x, -0.2, 2.2}, {y, -0.2, 2.2}, Axes -> False, Mesh -> None, 
                 ExclusionsStyle -> Directive[Thick, Red], PlotStyle -> None, 
                 BoundaryStyle -> Directive[Thick, Red], Boxed -> False, 
                 Lighting -> "Neutral", ImageSize -> 500]

enter image description here

Accurate approach

We will take only what we need to. ;)

following function replaces inequalities with equalities and looks for "convex hull" minimal sample of critical points of the region.

In this simple case (triangles) they can be used straightforwardly to create regions. for more complex regions it will require deeper analysis.

pointExtract[cond_] := Module[{ineq = {Less, LessEqual, GreaterEqual, Greater}, temp},
           temp = LogicalExpand@cond; (*<- important part, thanks to halirutan's 
                                        important remarks*)  
           temp = (temp /. {f_[x__, a__] :> Equal[x, a] /; MemberQ[ineq, f],
                            And -> Or}
                  ) /. Or -> List; (*making equalities*)
           temp = Tuples[temp, 2]; (*pairing them to each other*)
           DeleteDuplicates@Cases[{x, y} /. ((Quiet@Solve[#, {x, y}] & /@ temp)),
                                  {_?NumericQ ..}, \[Infinity]] (*solving paired equations*)
                    ]

Now we have to prepare set of inequalities:

eq = (List @@ B111[x, y])[[1, ;; , 2]] /. Or -> Sequence

points = DeleteCases[pointExtract /@ eq, {Repeated[{_, _}, 2]}]; 
(*we only take those with 3 or more points since we are not interested in lines and points*)
Graphics[{Hue@RandomReal[], Polygon[#]} & /@ points] (*domains plot*)

Below I have assumed that additional point is {1, 1, 1} (from B111 form) but it can be easily generalised.

Graphics3D[With[{len = Length@#},
GraphicsComplex[
         ({##, 0} & @@@ #)~Join~{{1, 1, 1}}, 
         {Hue@RandomReal[], Thickness@.01,
          Line[{##, len + 1} & @@@ Partition[{Sequence @@ Range[len], 1}, 2, 1]]}]
               ] & /@ points

          , Boxed -> False]

enter image description here

First, not accurate approach

The question is: how much do you need to know about those borders.

If you just want to plot the regions the following method is simple enough:

eq = (List @@ B111[x, y])[[1, ;; , 2]]

RegionPlot[eq, {x, -.1, 2.2}, {y, -.1, 2.2}, PlotPoints -> 50, PlotStyle -> None,
                                             BoundaryStyle -> Blue]

enter image description here

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • +1; I was just about to post something like this. It's worth pointing out that this solution relies on the fact that B111[x, y] is actually a Piecewise function that we can "look inside" (and not something involving Abs or Max or the like). –  Jul 17 '13 at 20:35
  • @RahulNarain Yes, I like it too :). I also like that Mathematica gives us easy access to the data produced inside Plot Piecewise etc. – Kuba Jul 18 '13 at 08:44
  • @Kuba Thanks for your solution! This goes way above my knowledge of Mathematica however, so what would I need to change to do the same thing for the function $B_{1111}(u,v)$ defined as B1111[x_, y_] = Integrate[B111[x + t, y - t], {t, 0, 1}]? – Ailurus Jul 18 '13 at 15:11
  • @Ailurus I can try to make someghing more general and useful but you have not respond to my question about edges in comment. Also I need to know what result you want to have, just a plot of smaller regions? Maybe all the edges like now? Do you need to know the coordinates or the plot is enough? :) – Kuba Jul 18 '13 at 19:09
  • @Kuba I just updated my question with the result I have in mind. The boundaries of all regions should be marked with a relatively thick black line. It is not necessary to highlight the supports of the regions as in your colourful example above :). If possible, it should be applicable without manually providing a set of coordinates. – Ailurus Jul 18 '13 at 21:15
  • @Kuba Now that I think of it, the result is actually the projection of the outlined supports of the regions onto the curve. – Ailurus Jul 18 '13 at 21:16
  • 1
    @Ailurus I've made an edit :) tell me if it is what you are looking for. – Kuba Jul 18 '13 at 22:57
  • @Kuba Yes this looks good, thanks for all the effort! However, it doesn't seem to work for $B_{1111}(x,y)$ as defined in my comment above. Mathematica mentions The first argument of Piecewise is not a list of pairs. Is this easily fixed? – Ailurus Jul 19 '13 at 07:13
  • @Ailurus You can try something like f[x_, y_] = Piecewise[First[List @@ #], None]&/@B1111[x, y] since it is sum of piecewise functions. however it looks quite smooth so you will get only the domain boundary on the plot. Tell im if this is helpful. (should there be x+t in second integration?) – Kuba Jul 19 '13 at 08:52
  • @Kuba Well, there are no warnings anymore, but the plot seems to be empty. Yes, the x + t should be in that integration, the resulting function $B_{1111}(x,y)$ is called the Zwart-Powell function. – Ailurus Jul 19 '13 at 09:00
  • 1
    @Ailurus I will take a closer look later, I do not have time now, sorry. – Kuba Jul 19 '13 at 09:02
  • @Kuba The second image on http://vectorizer.org/boar/gallery.html shows the ZP function/element. It consists of 28 pieces. These pieces should be outlined in the same fashion as your latest solution for the hexagonal hat function (which is in fact the Courant function/element). Thanks :) – Ailurus Jul 19 '13 at 09:09