• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
2
Question by WILEz1975 · Mar 10, 2017 at 02:16 PM · randomsphereinside

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:

alt text

sphereiside.jpg (121.8 kB)
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jayjf · Mar 10, 2017 at 02:58 PM 0
Share

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.

2 Replies

· Add your reply
  • Sort: 
avatar image
1

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 :-)

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Dec 02, 2017 at 02:22 PM 0
Share

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.

avatar image
0

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

Solved: alt text

The result in editor at runtime: alt text

Work fine!


screenshot-7.jpg (166.2 kB)
screenshot-8.jpg (183.3 kB)
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

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

Answers Answers and Comments

69 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to see a sphere from inside it 4 Answers

Random spawn script 1 Answer

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


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges