7

I was wondering if one could distribute points on a "cap" of a sphere, following a normal distribution of the points instead of a uniform distribution. This normal could be centered at the cap. Maybe one can use SpherePoints[]?

By "cap" I mean that we select only these points within a radius of some reference point. For instance, using the case for uniform points (from Carl Woll's answer here):

SeedRandom[1]
numberofPoints = 1000;
radiusofCap = .8;
ctr = RandomPoint[Sphere[]];
pts = RandomPoint[
   RegionIntersection[Ball[ctr, radiusofCap], Sphere[]], 
   numberofPoints];
Graphics3D[{Red, Point@pts, White, Opacity[.5], Sphere[]}]

We get:

enter image description here

How could we extend this so that the points are normal-distributed? A solution might be in the form:

myNormalCapPoints[sphereRadius_, capRadius_, numberofPoints_, std_] :=

Where we take the desired sphere and cap radius, then select a point on the sphere (randomly perhaps?), and generate the normal-distributed points around it with some standard deviation from the reference point.

Thanks!

Note/update 1: It would be like a 2D gaussian cloud of points on the surface of the sphere (at the "cap").

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
TumbiSapichu
  • 1,603
  • 8
  • 17

1 Answers1

8

Here I randomly rotate points away from the pole by a distance along the surface that is drawn from a truncated normal distribution. I hope this is close to what you need:

n = 1000;
capc = 0.4; (* Pi/2: cover hemisphere, Pi: cover the whole thing *)
dist = TruncatedDistribution[{-capc, capc}, NormalDistribution[0, 2]];
cvals = RandomVariate[dist, n];
dirs = Append[#, 0] & /@ RandomPoint[Circle[], n];
newpts = MapThread[RotationTransform[#1, #2][{0, 0, 1}] &, {cvals, dirs}];
Graphics3D[{Opacity[.5], Sphere[], Opacity[1], Point[newpts]}]

sphere cap normal distribution

flinty
  • 25,147
  • 2
  • 20
  • 86
  • .@flinty this is great! And a very simple way to have a "cap" from the truncated distribution. – TumbiSapichu Jul 11 '20 at 00:08
  • 1
    It should also work with other distributions and if you vary the standard deviation. If you want to move the cap to a different point other than {0,0,1} you should be able to rotate all the points after generating them first at {0,0,1} then applying a RotationTransform. Also if you increase the mean of the NormalDistribution from 0 to say 40, then you get a ring of points instead. – flinty Jul 11 '20 at 00:11
  • .@flinty, with the code as it is, it seems that varying the mean/std does not change the distribution of points. Do you know why? – TumbiSapichu Jul 11 '20 at 14:25
  • 1
    It does, you just have to increase the mean / stddev by quite a lot because of the truncation. Try replacing NormalDistribution[0, 2] with NormalDistribution[0, 0.1] and you'll see the difference. Same with NormalDistribution[80, 2] – flinty Jul 11 '20 at 14:27
  • Ohh, I see! I was setting things like NormalDistribution[0, 20000] with no perceptible change. But I see one has to decrease std instead (relative to the mean). I also see the ring effect you mention. Thanks! – TumbiSapichu Jul 11 '20 at 14:29