# Random insideUnitSphere but outside other UnitSphere?

I have a question, sorry for my bad English. I know and use Random.insideUnitSphere. Now I would like to create a random point inside the sphere, but outside another smaller sphere (with the same center).

Like:

Well the easy but not good solution would be to use a loop in that you create a random point in the outer sphere, check if it is inside the small excluded space and then create a new one if it is. That should do for most problems but can take a few iterations until you find a suitable point and it is not really a nice solution.

The better solution would probably be to create a random point within the radius of the outer sphere - radius of the inner sphere. Then you translate the point by a vector of length of the inner sphere radius into the negative direction towards the sphere center.

**Answer** by _dns_
·
Mar 10, 2017 at 03:48 PM

**EDIT**: this answer does not work, my mistake, thanks @Bunny83 for pointing it out!

randomValue = Random.insideUnitSphere

((1.0-smallSphereRadius/bigSphereRadius) + (smallSphereRadius/bigSphereRadius))bigSphereRadius;

To simplify/Optimize if needed

**TESTED but still imperfect answer:**
So, if I recall, I was trying to find a solution without normalizing because it still costs some CPU.

Solution with normalizing (corresponding to OP's solution) :

```
float delta = BigRadius - SmallRadius;
float length = SmallRadius + delta * Random.value;
Vector3 position = Random.insideUnitSphere.normalized * length;
```

Solution without normalizing (Notice it's using onUnitSphere)

```
float delta = BigRadius - SmallRadius;
float length = delta * Random.value;
Vector3 pos = Random.onUnitSphere * (BigRadius - length);
```

I've tested both and they seem to work the same.

I've timed both methods with a release build on an i7: method without normalizing is around 2.4 time faster (repeating a million time the last 2 lines, results might differ with IL2CPP). I could not see the internal code Unity uses because it's in C++

That being said, visually, it seems that both methods generate more points in the center than in the outer sphere (obvious when Comparing with a simple `Vector3 pos = Random.insideUnitSphere * BigRadius`

It shows that the distribution is not good with both methods (that rely on the same principle because the normalization is equivalent as taking a point on the sphere). There must be more math involved to have a uniform distribution (though it seems correct to discard values from Random.insideUnitSphere * BigRadius that are inside SmallRadius, not CPU efficient but uniform, as far as I understand)

**EDIT2 better solution:**
Ok, so I've recalled what I was trying to do first: I was trying to "compress" the random points inside the sphere = imagine a sphere with random points in it, then you slowly inflate the center until it reaches SmallRadius size, compressing all the points but not ejecting them out of the sphere. I think this conserves the uniform distribution, but I'm not mathematically sure it does. Visually, it works well and looks uniform, even with extreme values of radius (SmallRadius = 0 and SmallRadius = BigRadius - epsilon)

```
Vector3 posInSphere = Random.insideUnitSphere;
float length = posInSphere.magnitude;
float ratioRadius = SmallRadius/BigRadius;
Vector3 pos = (((1.0f-ratioRadius)*length + ratioRadius) / length) * BigRadius * posInSphere;
```

It involves computing a vector's magnitude so it's close to the cost of a normalization but it's better distributed anyway :-)

Just because a similar question has just been asked over here I stumbled on this question. I would like to say that this is not a solution and does not simplify anything. What your code actually does is this:

```
randomValue = Random.insideUnitSphere * bigSphereRadius;
```

That's because your bracket term:

```
((1.0-smallSphereRadius/bigSphereRadius) + (smallSphereRadius/bigSphereRadius))
```

is actually just "1". $$anonymous$$aybe it becomes more obvious when you substitude the ratio between the small and large radius with a variable

```
float ratio = smallSphereRadius / bigSphereRadius;
((1.0 - ratio) + (ratio)) ==
(1.0 - ratio + ratio) ==
(1.0)
```

It doesn't ensure a minimum distance at all. Note that the solution posted by the OP does work as he uses a normalized direction vector and calculates a length that has a minimum length + some random "addition". However the "outterRadius$$anonymous$$ultiplier" doesn't specify the outer radius but the max addition to the inner radius. So the max radius is the inner radius + the outer radius.

**Answer** by WILEz1975
·
Mar 10, 2017 at 08:48 PM

**Solved**:

The result in editor at runtime:

Work fine!

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Random spawn script 1 Answer

How to see a sphere from inside it 4 Answers

Random Number every 5 seconds 2 Answers

Help with Randomized Sprite on GUI button click 0 Answers

Randomly generate blocks on a flat map 0 Answers