# RegionMember - RegionPlot3D vs ImplicitRegion

Posted 5 months ago
891 Views
|
7 Replies
|
6 Total Likes
|
 My plan is to effect a 3D extrusion by forming a cross section region in the x-y plane, R, say, then use RegionMember[R,{x,y}] as part of the implicit specification of a 3D region extending from zMin to zMax.I'll start with what appears to work. I picked a regular pentagon cross section, and generated from it an object that appears to have a Head == MeshRegion and that returns True to MeshRegionQ. (a condition not guaranteed, I've found.) xSection = DiscretizeRegion[RegularPolygon[5]] {Head[#], MeshRegionQ[#]}&@% // TableForm When I use membership in xSection as part of the specification of bounds for a RegionPlot3D, a Graphics3D is returned, and that can be converted to an apparently legal MeshRegion using DiscretizeGraphics[] thus: DiscretizeGraphics[ RegionPlot3D[ RegionMember[xSection, {x, y}] , {x, -1., 1.} , {y, -1., 1.} , {z, -0.5, 0.5} ] ] {Head[#], MeshRegionQ[#]}&@% // TableForm The return is a presentable prismatic extrusion, subject to the limitations of RegionPlot3D. Applying the form to ImplicitRegion fails, though. ImplicitRegion[ RegionMember[xSection, {x, y}] , {x, y, {z, -0.5, 0.5}} ] ImplicitRegion::bcond: RegionMember[,{x,y}] should be a Boolean combination of equations, inequalities, and Element statements. I sort of get that RegionMember returns True/False if I give it a "numeric point" (I suppose that's how RP3D works), but it also offers to "gives conditions for the point {x,y,[Ellipsis]} to be a member of reg.".It seems like that should be a "Boolean combination of equations." RegionMember[reg] returns a RegionMemberFunction, but that doesn't seem to work as I expected either.  rmf = RegionMember[xSection] ImplicitRegion[ rmf[{x, y}] , {x, y, {z, -0.5, 0.5}}] ImplicitRegion::bcond: RegionMemberFunction[,2,RegionMeshCanonicalDistance[True]][{x,y}] should be a Boolean combination of equations, inequalities, and Element statements. What is it about this I don't understand?Cheers, Fred
7 Replies
Sort By:
Posted 5 months ago
 If you just want to generate a "presentable prismatic extrusion", then - keeping things simple - a most straight way would be: prism5Reg = Region@RegionProduct[RegularPolygon[5], Line[{{-1/2}, {1/2}}]] What you are doing looks pretty complicated, and it is not clear to me what you finally want to achieve.
Posted 5 months ago
 Henrik,Thanks for the reply and the elegant construction.I often do things in very complicated ways, and besides that, I had never heard of Cartesian products until Version 10, so they haven't worked their way to the top level in my toolbox.With Regions, it's easy to get led down complicated paths. Armed with the sketchy map of the documentation, I often wander, either with random or exhaustive search, and I look for some consistencies.I'd really like to understand why ImplicitRegion doesn't work that way, though.Cheers, Fred
Posted 5 months ago
 Hi Fred, I'd really like to understand why ImplicitRegion doesn't work that way, though. ... but it does work (well, at least like so), try: xSection = RegularPolygon[5]; reg1 = ImplicitRegion[RegionMember[xSection, {x, y}], {x, y, {z, -0.5, 0.5}}]; rmf = RegionMember[xSection]; reg2 = ImplicitRegion[rmf[{x, y}], {x, y, {z, -0.5, 0.5}}]; RegionPlot3D /@ {reg1, reg2} Regards -- Henrik
Posted 5 months ago
 Some results of a random search. First, a navigation tool: regInfo[r_] := {{#}, {"Head", Head[#]}, {"Region?", RegionQ[#]}, {"MeshRegion?", MeshRegionQ[#]}, {"BoundaryMeshRegion?", BoundaryMeshRegionQ[#]}, {"SolidRegion?", SolidRegionQ[#]}, {"ConstantRegion?", ConstantRegionQ[#]}, {"Dimension", RegionDimension[#]}, {"Embedding Dimension", RegionEmbeddingDimension[#]}} &@r // TableForm It is not necessary (even harmful evidently) to discretize the Polygon to a MeshRegion to use in RegionMember as I did in my original post. p5 = RegularPolygon[5]; regInfo[%] The Polygon p5 can be fed directly to the RegionMember for use in an ImplicitRegion. The result can then be discretized to a MeshRegion. ImplicitRegion[ RegionMember[p5, {x, y}] && -0.5 <= z <= 0.5, {x, y, z}]; regInfo[%] DiscretizeRegion[%%]; regInfo[%] Could I have worked this out from the documentation? Not in a million years.Cheers, Fred
Posted 5 months ago
 :) you did work it out.  ImplicitRegion[cond,{Subscript[x, 1],\[Ellipsis],Subscript[x, n]}] but the docs and examples say to use "cond", so you know a mesh would not work?
Posted 5 months ago
 John, Thanks for keeping this discussion alive."but the docs and examples say to use "cond", so you know a mesh would not work?"I'm not that bright or insightful. I'll try to explain. To my mind, RegionMember[ ] is a perfectly respectable 'cond', working in a way I think is predictable, but the inconsistencies clutter up my thinking. regInfo[r_] := {{#}, {"Head", Head[#]}, {"Region?", RegionQ[#]}, {"MeshRegion?", MeshRegionQ[#]}, {"BoundaryMeshRegion?", BoundaryMeshRegionQ[#]}, {"SolidRegion?", SolidRegionQ[#]}, {"ConstantRegion?", ConstantRegionQ[#]}, {"Dimension", RegionDimension[#]}, {"Embedding Dimension", RegionEmbeddingDimension[#]}} &@r // TableForm p5 = RegularPolygon[5]; regInfo[%] p5Mesh = DiscretizeRegion[p5]; regInfo[%] Both p5 and p5Mesh are Regions and ConstantRegions, so they're legal arguments for RegionMember[]. As a Boolean expression (in the sense that it returns True or False when fed point co-ordinates {x, y}), RegionMember[] behaves in an uncomplicated way in uncomplicated circumstances: Graphics[ {If[RegionMember[p5, #], Red, LightGray], Point[#]} & /@ RandomReal[{-1, 1}, {1000, 2}] , ImageSize -> Tiny] Graphics[ {If[RegionMember[p5Mesh, #], Red, LightGray], Point[#]} & /@ RandomReal[{-1, 1}, {1000, 2}] , ImageSize -> Tiny] RegionPlot[], digests RegionMember[p5, {x, y}], gags a little on RegionMember[p5Mesh, {x, y}], but both forms give presentable, indistinguishable plots with numerically similar, if not ===, parts.. RegionPlot[RegionMember[p5, {x, y}], {x, -1.1, 1.1}, {y, -1.1, 1.1}, ImageSize -> Tiny] Quiet@RegionPlot[ RegionMember[p5Mesh, {x, y}], {x, -1.1, 1.1}, {y, -1.1, 1.1}, ImageSize -> Tiny] Max@Flatten[%[[1, 1, 1]] - %%[[1, 1, 1]]] The 2D versions of RegionMember[p5] and RegionMember[p5Mesh] seem to work interchangeably in RegionPlot3D[]: RegionPlot3D[RegionMember[p5, {x, y}], {x, -1.1, 1.1}, {y, -1.1, 1.1}, {z, -0.5, 0.5}, ImageSize -> Tiny] RegionPlot3D[RegionMember[p5Mesh, {x, y}], {x, -1.1, 1.1}, {y, -1.1, 1.1}, {z, -0.5, 0.5}, ImageSize -> Tiny] but ImplicitRegion[] is the holdout. ImplicitRegion[RegionMember[p5, {x, y}], {x, y}] ImplicitRegion[RegionMember[p5Mesh, {x, y}], {x, y}] In summary, no, it's still not clear to me that a mesh shouldn't work.That isn't to say I'd now want to use it for an extrusion, but how about a helical extrusion? What's the synthetic geometric element for a screw transform?Cheers, Fred
Posted 4 months ago

It's rude to answer your own questions, but here goes anyway. Here are some ways to shear and twist prisms. To follow along, go up, copy, paste and run the regInfo[] function.

The purpose is to show ways to build extrusions, skew and twist them.

## 2D Regions

p5 = RegularPolygon[{1., 0}, 5];
Rotate[Region[p5, ImageSize -> Tiny, Axes -> True], 0, {0, 0}]
Rotate[Region[p5, ImageSize -> Tiny, Axes -> True], Pi/6, {0, 0}]
Rotate[Region[p5, ImageSize -> Tiny, Axes -> True], Pi/6, {1, 0}]


## Pentagonal Extrusion

To extrude it into a prism:

prism5 = RegionProduct[p5, Line[{{-0.5}, {0.5}}]];
regInfo[%]


## Exskewsion

To shear it into a skew prism (an "exskewsion" - you read it here first.) the ShearingTransform works:

Region[
TransformedRegion[
prism5
, ShearingTransform[Pi/10, {1, 0, 0}, {0, 0, 1}]
]
, Axes -> True
]


## Exscrewsion

To twist it uniformly about its axis: (an "exscrewsion" - you read it here first.)

The expected form for the function describing a rotation about the z axis through the origin for use in TransformedRegion is:

RotationTransform[\[Theta], {0, 0, 1}]


I haven't figured out how to deal with the 4D projected space here, but a brute force hack works. Making the rotation angle linear in z makes the transform itself nonlinear, so write out the function explicitly. Notice the dot product appears explicitly. In terms of the pitch of the screw in radians/axial distance:

fScrew[pitch_] := {
{
Cos[pitch #[[3]]], -Sin[pitch #[[3]]], 0}
, {Sin[pitch #[[3]]], Cos[pitch #[[3]]], 0}
, {0, 0, 1}
}.# &;


and the twisted region becomes:

    Region[
TransformedRegion[prism5
, fScrew[Pi/5]
]
, Axes -> True
]


## Offset Exscrewsion

For rotation of a cross section about the z axis through a point not the origin, construct a form to match

RotationTransform[\[Theta], {0, 0, 1}, {x0, y0, 0}]


Brute force again - even more so because the dot product is written explicitly:

fOffsetScrew[pitch_, {x0_, y0_}] := {
Cos[pitch #1[[3]]] #1[[1]] - Sin[pitch #1[[3]]] #1[[2]] +
x0 (1 - Cos[pitch #1[[3]]]) + y0 Sin[pitch #1[[3]]]
, Cos[pitch #1[[3]]] #1[[2]] + Sin[pitch #1[[3]]] #1[[1]] +
y0 (1 - Cos[pitch #1[[3]]]) - x0 Sin[pitch #1[[3]]]
, #[[3]]
} &;

Region[
TransformedRegion[
prism5
, fOffsetScrew[Pi/5, {1, 0}]
]
, Axes -> True
, PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}, {-1, 1}}
]


That's all I got for now.

Cheers,

Fred