# How to build the following region?

Consider a 3D figure defined by the dependence $$\Delta x(z),\Delta y(z)$$. One example is a pyramidal frustum, for which $$\Delta x, \Delta y$$ are linear functions of $$z$$, and $$z$$ lies inside the interval $$z_{\text{min}} where $$z_{\text{vertex}}$$ is the value of $$z$$ at which $$\Delta x=\Delta y = 0$$. The corresponding region (reg) may be obtained in Mathematica as an intersection of the pyramid (pyramid) and the cuboid (cuboid) with the transverse dimensions equal to the maximal $$\Delta x, \Delta y$$:

Dxin = 3;
Dxout = 1;
xcenter = 5;
Dyin = 6;
Dyout = 2;
ycenter = 0;
zmin = 450;
zmax = 460;
Dxz[z_] =
Dxin (zmax - z)/(zmax - zmin) + Dxout*(z - zmin)/(zmax - zmin);
Dyz[z_] =
Dyin (zmax - z)/(zmax - zmin) + Dyout*(z - zmin)/(zmax - zmin);
zvertex = z /. Solve[Dxz[z] == 0., z][[1]];
pyramid =
Pyramid[{{xcenter - Dxin/2, ycenter - Dyin/2,
zmin}, {xcenter - Dxin/2, ycenter + Dyin/2,
zmin}, {xcenter + Dxin/2, ycenter + Dyin/2,
zmin}, {xcenter + Dxin/2, ycenter - Dyin/2, zmin}, {xcenter,
ycenter, zvertex}}];
cube = Cuboid[{xcenter - Dxin/2, ycenter - Dyin/2,
zmin}, {xcenter + Dxin/2, ycenter + Dyin/2, zmax}];
reg = RegionIntersection[pyramid, cube];
Region[reg]


I am wondering how it may be possible to define a region reg2 with the same geometry as in the previous example but with Dyout = 1 instead of Dyout = 2, i.e., the $$y$$ dimensions shrink faster than the $$x$$ dimensions.

Edit

This is my solution:

tempreg =
ImplicitRegion[
xcenter - Dxz[z]/2 < x < xcenter + Dxz[z]/2 &&
ycenter - Dyz[z]/2 < y < ycenter + Dyz[z]/2 &&
zmin < z < zmax, {x, y, z}];
reg2 = RegionIntersection[cube, tempreg];


However, 1) it works very slowly since it deals with implicit regions, and 2) the region contains ugly meshes. I need a fast working and accurate solution since I will later use it to compute some geometric acceptances, etc.

To speed it up, I may discretize it:

reg2= DiscretizeRegion[RegionIntersection[cube, tempreg],
MaxCellMeasure -> "Volume" -> 1];
Region[reg2]


But it is still ugly, and not accurate: say, RegionMeasure returns ~77.33 instead of 78.33 as it must be.

If decreasing MaxCellMeasure, I will, of course, improve the accuracy but slow down all the operations. Even the value 10^-3 does not give the very well accuracy, while slowing down everything significantly.

Somewhat improving your code, the following works well for me.

Dxout = 1;xcenter = 5;Dyin = 6;Dyout = 1;ycenter = 0;zmin = 450;zmax = 460;
Dxz[z_] =  Dxin (zmax - z)/(zmax - zmin) + Dxout*(z - zmin)/(zmax - zmin);
Dyz[z_] =  Dyin (zmax - z)/(zmax - zmin) + Dyout*(z - zmin)/(zmax - zmin);
cube = Cuboid[{xcenter - Dxin/2, ycenter - Dyin/2,
zmin}, {xcenter + Dxin/2, ycenter + Dyin/2, zmax}];
tempreg =  ImplicitRegion[Reduce[xcenter - Dxz[z]/2 < x < xcenter + Dxz[z]/2 &&
ycenter - Dyz[z]/2 < y < ycenter + Dyz[z]/2 &&
zmin < z < zmax] // Simplify, {x, y, z}];
inter = RegionIntersection[tempreg, cube];
Volume[inter] // Timing


{6.04688, 235/3}

RegionPlot3D[ RegionMember[inter, {x, y, z}], {x, 2, 8}, {y, -5, 5}, {z, 445, 465},PlotPoints -> 50]


works slowly, but the result is not so bad:

• Thanks! However, the graphical representation still looks like a piece of cake nibbled by a beaver. Nov 27, 2023 at 21:03
• @JohnTaylor: See the addition to my answer. Nov 27, 2023 at 21:18

It seems that it may be possible to do this in the following way: we may define another pyramid with $$dy(z)$$ being Dyz[z] but $$dx(z)$$ corresponding to the $$z$$ dependence which vanishes at the same $$z$$ as Dyz[z]:

zvertex2 = z /. Solve[Dyz[z] == 0., z][[1]];
DxzFakeTemp[DxIn_, z_] =
DxIn*(zmax - z)/(zmax - zmin) + Dxout*(z - zmin)/(zmax - zmin);
DxInFake = DxIn /. Solve[DxzFakeTemp[DxIn, zvertex2] == 0, DxIn][[1]];


Then, the intersection of this region with reg as defined in my question would produce an accurate result:

pyramid2 =
Pyramid[{{xcenter - DxInFake/2, ycenter - Dyin/2,
zmin}, {xcenter - DxInFake/2, ycenter + Dyin/2,
zmin}, {xcenter + DxInFake/2, ycenter + Dyin/2,
zmin}, {xcenter + DxInFake/2, ycenter - Dyin/2, zmin}, {xcenter,
ycenter, zvertex2}}];
reg3 = RegionIntersection[pyramid2, reg];


Here, reg3 is the desired region. I am still wondering, however, whether it may be possible to do this in a different way, possibly to generalize to more complicated geometries.