Minecraft 1.14: How to check if a player has a position with a specific y-axis within a circular x,z area [duplicate]

I built a flat circular plane in minecraft, and am trying to force players to remain within this area. The circle is 161x161 centered around 0, 44, 0. I then placed a command block at the very center, with the command tp @a[rm=80,r=85] 0 45 0. This teleports everyone more than 80 and less than 85 blocks from the command block back to the center of the circle, creating basically a hemisphere (the sphere is cut in half by the circular plane) to move within.

However, I want to instead restrict movement to a cylinder from y=44 to y=infinity. With this method you would only be teleported when your x and z coordinates exceeded the boundary of the 161x161 circle, ignoring your y coordinate. You would be able to stand at the edge of the circle and fly up as high as you wanted without being teleported. This does need to keep the same property of the previous command to not teleport players outside 85 blocks. It will only teleport those who have an x and z change of between 80 and 85 blocks ( 85>sqrt(x²+y²)>80 )

I tried variations of the command involving the dy argument, but this only removed the teleport all together.

Note: If it is not possible to have an infinite height limit, restricting to any value above y=70 would also work. In addition, the ideal minimum of y=44 can be changed, but not increased.


To expand on Fabian's first solution i bring example of how to implement it.

First of we need to setup a scoreboard objective

/scoreboard objectives add inCylinder dummy inCylinder

By using this command we create a scoreboard objective InCylinder that can hold any number,

Then we summon 1 armor stand with coordinate 0 on y axis, so

/summon armor_stand 413 0 456 {NoGravity:1b}

413 is the x coordinate of the center of the cylinder,

456 is the z coordinate of the center of the cylinder,

0 shouldn't be changed

next step is to summon armor stands recursively above the original armor stand, Backup your world before doing this step

/execute @e[type=armor_stand,c=-1] ~ ~ ~ summon armor_stand ~ ~1 ~ {NoGravity:1b}

you put this in a repeating command block and let it run for ~14 seconds to summon armor stands up to y=256 because you can't build above 256 it would be useless to summon armor stands

now for the actual detecting

execute @e[type=armor_stand] ~ ~ ~ execute @a[r={SPECIFY_RADIUS_HERE}] ~ ~ ~ scoreboard players set @s inCylinder 2

put the above command into a repeating command block, and set it to always active, then connect it to a chain command block (always active)

execute @a ~ ~ ~ scoreboard players remove @s inCylinder 1

then the last chain command block does

execute @a[score_inCylinder=0] ~ ~ ~ {YOUR_COMMAND_HERE}

I don't think this is exactly possible. The three types of area related target selector arguments are x/y/z, dx/dy/dz and r/rm. x/y/z moves the starting point, dx/dy/dz form a cuboid and r/rm forms a sphere. If you combine the two, you can only select the cross area of the two. This can never form a cylinder.

But you can approximate it. You want to target players flying out anyway, so with the maximum speed in Spectator you won't detect them at exactly the border anyway (because command blocks/functions are restricted to 20/s and you can move up to 4 blocks in that time in Spectator mode. So you don't need to be perfectly exact with it anyway. Here are two solutions for an approximation:

Solution 1, approximating the mantle: You can put armor stands along the center axis of the cylinder (every 10 blocks should be enough), then give every player inside a radius around them a tag and then teleport everyone without the tag. Don't forget to remove the tag from everyone (*) afterwards! This makes your space look a bit like a pyramid cake (without the hole in the middle):

pyramid cake

Solution 2, approximating the area: You can use multiple rectangles to approximate the circle. You can either do it like it's done in limit calculations:

rectangle approximation

or use the rectangles you get here (drag the point), that would probably lower the amount of rectangles you need for the same accuracy. Again, you would tag everyone inside with dx/dy/dz (y=0,dy=256), then teleport everyone without a tag and then remove the tag. This way your area would look like when someone builds a circle in Minecraft out of blocks, but you can choose the resolution.