4
$\begingroup$

I have a region specified as a simple closed curve, suitable for ParametricPlot (as in this question).

What is the easiest way to restrict 3D plot to only plot points inside this region?

An example application is here -- I'm plotting resolvent and range of matrix as separate Plot3D and ParametricPlot, but I'd like to combine them into a single Plot3D by using RegionFunction argument. However, that takes a region membership function, but I instead have a curve of the boundary.

ClearAll["Global`*"];
n = 3;

badMat[eps_] := Module[{mat},
   mat = RotateLeft@IdentityMatrix[n];
   mat[[n, 1]] = eps;
   mat
   ];

fval[mat_?SquareMatrixQ, t_?NumericQ] /; 
   Internal`EffectivePrecision[mat] < \[Infinity] || 
    InexactNumberQ[t] := 
  Module[{tm, v}, tm = (# + ConjugateTranspose[#])/2 &[mat Exp[I t]];
   v = Quiet[
     Check[First[
       Eigenvectors[tm, 1, 
        Method -> {"Arnoldi", "Criteria" -> "RealPart"}]], 
      MaximalBy[Transpose[Eigensystem[tm]], First][[1, -1]], 
      Eigenvectors::arall]];
   (Conjugate[v] . mat . v)/(Conjugate[v] . v)];

pr = {{-1, 1}, {-1, 1}};

epsVals = {0.01, .1, .5, .9};

rangePlot[mat_] := 
  With[{eigs = Eigenvalues[mat]}, 
   ParametricPlot[ReIm[fval[mat, t]], {t, 0, 2 \[Pi]}, 
    Epilog -> {AbsolutePointSize[10], ColorData[97, 2], 
      Point[ReIm[eigs]]}, PlotRange -> pr]];

resolventPlot[mat_] := Module[{},
   eigs = Eigenvalues[mat];
   c = Norm[mat];
   n = Length[mat];
   spectraPlot = 
    Plot3D[-c Log10[
       First[SingularValueList[
         mat - SparseArray[Band[{1, 1}] -> x + I y, {n, n}], -1, 
         Method -> "Arnoldi", Tolerance -> 0]]], {x, -2, 4}, {y, -4, 
      4}, AspectRatio -> Automatic, PlotRange -> {-1, 1},
     MeshFunctions -> {#3 &}, Boxed -> False, Axes -> False
     ]
   ];

Print["Matrices"];
Table[MatrixForm[badMat[eps]], {eps, epsVals}]
Print["Resolvents"];
Table[resolventPlot[badMat[eps]], {eps, epsVals}]
Print["Numeric ranges"];
Table[rangePlot[badMat[eps]], {eps, epsVals}]

enter image description here

$\endgroup$

1 Answer 1

7
$\begingroup$

By

regs = BoundaryDiscretizeGraphics /@ fig2ds

we get the 4 regions.

enter image description here

So we add

reg = BoundaryDiscretizeGraphics@ParametricPlot[ReIm[fval[mat, t]] // Evaluate, {t, 0, 2 π}];
regm = RegionMember@reg;

and set RegionFunction -> Function[{x, y, z}, regm@{x, y}]

Clear[resolventPlot2];
resolventPlot2[mat_] := Module[{}, eigs = Eigenvalues[mat];
  c = Norm[mat];
  n = Length[mat];
  reg = BoundaryDiscretizeGraphics@
    ParametricPlot[ReIm[fval[mat, t]] // Evaluate, {t, 0, 2 π}];
  regm = RegionMember@reg; 
  spectraPlot = 
   Plot3D[-c Log10[
      First[SingularValueList[
        mat - SparseArray[Band[{1, 1}] -> x + I y, {n, n}], -1, 
        Method -> "Arnoldi", Tolerance -> 0]]], {x, -2, 4}, {y, -4, 
     4}, AspectRatio -> Automatic, PlotRange -> {-1, 1}, 
    MeshFunctions -> {#3 &}, Boxed -> False, Axes -> False, 
    RegionFunction -> Function[{x, y, z}, regm@{x, y}]]]
Table[resolventPlot2[badMat[eps]], {eps, epsVals}]

enter image description here

$\endgroup$
1
  • $\begingroup$ Thanks for the find, BoundaryDiscretizeGraphics seems like the trick $\endgroup$ Jul 27, 2023 at 0:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.