Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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 /
avatar image
0
Question by NibblesMeKibbles · Mar 24, 2020 at 04:16 PM · c#distancegridsphere

Find all integer grid points inside sphere

Given a position (Vector3) and a radius (float) of a sphere, how do I grab all integer coordinates inside the sphere?

My current solution was originally a inefficient hack to get radius = ~1 working, but now that the surrounding functionality is complete I am currently drawing blanks for how to tackle this seemingly simple problem.


 public HashSet<Vector3> GetGridPoints(Vector3 pos, float radius = 0.87f) {
     HashSet<Vector3> gridPoints = new HashSet<Vector3>();
     int radiusCeil = Mathf.CeilToInt(radius);
     for (int i = -radiusCeil; i <= radiusCeil; i++) {
         for (int j = -radiusCeil; j <= radiusCeil; j++) {
             for (int k = -radiusCeil; k <= radiusCeil; k++) {
                 Vector3 gridPoint = new Vector3(Mathf.Floor(pos.x + i),
                                                 Mathf.Floor(pos.y + j),
                                                 Mathf.Floor(pos.z + k));
                 if (Vector3.Distance(pos, gridPoint) <= radius) {
                     gridPoints.Add(gridPoint);
                 }
             }
         }
     }
     return gridPoints;
 }

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Mar 24, 2020 at 06:17 PM

Uhm I don't really see any issues with your code. The overall approach is totally fine. What you can do is avoid Vector3.Distance and just use

 float distSqr = gridPoint.x*gridPoint.x + gridPoint.y*gridPoint.y + gridPoint.z*gridPoint.z;
 if (distSqr < radiusSqr)
     gridPoints.Add(gridPoint);

Since you want integer coordinates you might want to replace your Vector3 by Vector3Int. While using floating point numbers for integer values work pretty well for relatively small values, you could get into issues when the values are getting large.


Note that instead of calculating the squared length of the vector manually you could use gridPoint.sqrMagnitude which does the same thing. However inlined it will be faster.


Finally a sphere has about ‭52.36% volume as it's bounding box. So yes, you're checking about twice the points you will need in the end. It's possible to slightly adapt the ranges of the for loops to cut away the corners of the bounding cube. However that requires quite a bit of math and overhead so it probably won't help you with performance.


Another possible improvement is your choice of data structure. The HashSet class unfortunately doesn't have a way to set the internal capacity. For a large number of additions that would result in several resize operations which will require to move all already stored elements into a new array.

If you don't really need a hashset you should switch to a List instead. There you can simply set the capacity ahead of time to something like this:

 a = radiusCell*2+1;
 capacity = (int)(a*a*a* 0.55f);

This should result in a slightly larger capacity than what you actually need so no resize should happen.


If you really need a hashset I'm just wondering for what purpose. If you just want to test if a point is inside that sphere it would be simpler to just store the center and radius and do the exact same test on the fly for the point you want to test.


Finally keep in mind that using Vector3 in a hashset is dangerous since a Vector3 consists of 3 floating point values. You will only find an match if all 3 values are exactly the same. Even the slightest variation would make it a different value. Therefore Vector3Int is highly recommended in such a case.

Comment
Add comment · Show 2 · 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 NibblesMeKibbles · Mar 24, 2020 at 06:54 PM 0
Share

Wow, Vector3Int is a thing apparently. That's going to make my life so much easier, lots of happy refactoring to do now.

I chose HashSet because I saw performance analysis in various threads/posts that it out-performs at larger index sizes. $$anonymous$$aybe I can do a few tests for my own situation and try out your capacity recommendation as well.

The main purpose of this post was to ensure I wasn't missing something stupidly obvious like a built-in function or easy math to iterate over a defined int grid (besides a cubed for-loop, which as you mentioned the 48% loss). Thanks for all the help/suggestions!

Edit: Vector3Int.forward doesn't exist? Neat.

avatar image Bunny83 NibblesMeKibbles · Mar 24, 2020 at 08:49 PM 0
Share

No, HashSet will be as slow as an default sized List if not slower when it comes to adding elements. As you can read over here:

If Count already equals the capacity of the HashSet<T> object, the capacity is automatically adjusted to accommodate the new item.

If Count is less than the capacity of the internal array, this method is an O(1) operation. If the HashSet<T> object must be resized, this method becomes an O(n) operation, where n is Count.

That behaviour is similar to List but with a List you can actually preallocate the memory (If you know how much you're going to need). Also note that most collections will simply double the capacity when it runs out of space. So typical default values are 4 or 8 elements. That means after every power of two elements the old internal array would be thrown away (up for garbage collection) and a new one with double the size would be allocated. So if for example "radiusCeil" is 5 (an 11x11x11 area) the sphere would contain roughly 697 points. So the structure would need to grow to 8,16,32,64,128,256,512 and finally to 1024. When you set the capacity to 11²*0.55 == 732 to begin with all points should fit inside that structure.


Note that a HashSet is there to represent the mathematical concept of a set. You only want to use such a structure when you want to perform set operations like a testing of a certain value exists in the set. If you don't need this there's no point in using a HashSet. As I said If you need to test somewhere else if a certain point is in the sphere, you can simply use the same math you used to create your hash set on the fly.


Yes Vector3Int does not have a forward property. Actually the Vector3 forward property is a bit slower than just using new Vector3(0,0,1) Actually Vector3.forward is just 3 characters shorter so not a huge benefit. Yes it's slightly more readable but not really necessary.

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.

Follow this Question

Answers Answers and Comments

698 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 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 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 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 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 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 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 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 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 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Turning my grid of particles into a sphere 0 Answers

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

C# Creating a 2d boundary 1 Answer

Get Distance From Mouse To Canvas BoxCollider 1 Answer


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