The classic, simple and efficient solution is to use a plugin like Essentials to define a precise spawn position. But you need to use bukkit spigot or some other modified server.
If you are on vanilla minecraft (no modification), a workaround is to put pressure plates on all potential spawn places (20x20 => [http[https://minecraft.gamepedia.comwiki/w/Spawn#World_spawn][1]) which will activate command block(s).
Then you have 2 options:
The first is simply to teleport players to the position you want:
tp <player> <x> <y> <z>
for example (if 123 456 789 is the world spawn point):
tp @a[x=123,y=456,z=789,r=11] 987 654 321
(r is the radius and if you want to keep a random on spawn point you can use relative coordinates (using "~").
- The second solution is to use a fill clock:
(search it on google to know what it is and how to create one).
How to (re)start a fill clock:
setblock <x> <y> <z> air
setblock <x> <y> <z> redstone_block
As x,y,z put the coordinates of the first redstone_block of the fill clock.
What to put on the fill clock: tp @a[x=123,y=456,z=789,r=11] 987 654 321
If you want to be more precise on the area where players must be TP use a invisible ArmorStand with PersistenceRequired:1 to define at first point of the area and use "dx", "dy" and "dz" parameters in the selector to define the relative coordinates of the second point of your area. It will result in a command like this one:
execute @e[type=ArmorStand,name=MyAreaFirstPoint,c=1] ~ ~ ~ tp @a[dx=20,dy=3,dz=20] <x> <y> <z>