• 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 MagicianArtemka · Apr 28, 2021 at 10:02 PM · c#mathalgorithmgeometry

How to find centers of inner child of a quad (geometry guy needed)?

The same question on the Unity Forum with readable text - https://forum.unity.com/threads/how-to-find-centers-of-inner-child-of-a-quad-geometry-guy-needed.1100416/

Hi, I have not very big experience in the game development sphere (around 4 years), but I have collided with this problem at least 2 times already. And every time I solved it with the stupidest method. Now I have collided with it 3rd time and I need to solve it in a smart way.

Problem description:

Imagine, that we have a plane (quad or rectangle) [img. 1]. We want to split it into 4 children of the same size. We know all about this plane - its dimensions and center position. So we easily calculated the child's plane size and ready to move on. What we need to do next - is to define where we want to place every child. And this is the task - "how to find child plane position in the smartest (and possibly the fastest way)?"

alt text

The result we want to achieve

alt text

All next info was based on the concept that we decide that we want to find centers of that small planes.

Solution 1 - Cavemen calculations

The ugliest way to resolve this task. I used it before when I need to resolve this kind of problem. And it works pretty robustly, like stone, that was taped to the stick by our grandgrandgrandfather. But this solution is ugly. It will produce a tone of bugs. It hard-to-modify solution. And it will be even more complicated for 3D.

The code of the solution

 public void Split ()
 {
     Vector3 nodeBoundsExtents = NodeBounds.extents;
     float nodeBoundsExtentsX = nodeBoundsExtents.x;
     float nodeBoundsExtentsZ = nodeBoundsExtents.z;
     Vector3 childBoundsSize = new Vector3(nodeBoundsExtentsX, 0, nodeBoundsExtentsZ);
     Vector3 childBoundExtents = childBoundsSize / 2.0f;
     Vector3 nodeCenterPosition = NodeBounds.center;
  
     Vector3[] childPositions =
     {
         new Vector3(nodeCenterPosition.x, 0, nodeCenterPosition.z) - childBoundExtents,
         new Vector3(nodeCenterPosition.x, 0, nodeCenterPosition.z) + childBoundExtents,
         new Vector3(nodeCenterPosition.x - childBoundExtents.x, 0, nodeCenterPosition.z + childBoundExtents.z),
         new Vector3(nodeCenterPosition.x + childBoundExtents.x, 0, nodeCenterPosition.z - childBoundExtents.z)
     };
  
     foreach (Vector3 childPosition in childPositions)
     {
         CreateChild(childPosition, childBoundsSize);
     }
 }
  
 private void CreateChild (Vector3 centerOfTheNewChild, Vector3 childBoundsSize)
 {
     GameObject child = new GameObject();
     BoxCollider boxTest = child.AddComponent<BoxCollider>();
     boxTest.size = childBoundsSize;
     child.transform.position = centerOfTheNewChild;
 }

This solution is based on one action - we just get the center of the big plane and shift it with offset with size of the small quad in different directions.

Solution 2 - When you try to impress your crush with your math skills

This solution is a bit better than the first, but it has a few cons:

  • It doesn't intuitive and it not stupid and simple

  • It can produce strange results when you will mess with the mirror vector.

  • It will become completely messy in 3D.

The code of the solution

 public void Split ()
 {
     Vector3 nodeBoundsExtents = NodeBounds.extents;
     float nodeBoundsExtentsX = nodeBoundsExtents.x;
     float nodeBoundsExtentsZ = nodeBoundsExtents.z;
  
     Vector3 childBoundsSize = new Vector3(nodeBoundsExtentsX, 0, nodeBoundsExtentsZ);
     Vector3 childBoundExtents = childBoundsSize / 2.0f;
     Vector3 nodeCenterPosition = NodeBounds.center;
  
     Vector3 firstQuadCenter = new Vector3(nodeCenterPosition.x, 0, nodeCenterPosition.z) - childBoundExtents;
  
     Vector3[] childPositions =
     {
         firstQuadCenter,
         firstQuadCenter * -1,
         Vector3.Reflect(firstQuadCenter, Vector3.right),
         Vector3.Reflect(firstQuadCenter, Vector3.forward)
     };
  
     foreach (Vector3 childPosition in childPositions)
     {
         CreateChild(childPosition, childBoundsSize);
     }
 }
  
 private void CreateChild (Vector3 centerOfTheNewChild, Vector3 childBoundsSize)
 {
     GameObject child = new GameObject();
     BoxCollider boxTest = child.AddComponent<BoxCollider>();
     boxTest.size = childBoundsSize;
     child.transform.position = centerOfTheNewChild;
 }

Looks smart, doesn't it? We used magical Vector3.Reflect() and g̶e̶t̶ ̶b̶u̶n̶n̶y̶ ̶o̶u̶t̶ ̶f̶r̶o̶m̶ ̶a̶ ̶h̶a̶t̶ made our code a bit smaller. You can show this code to your crash and she/he will probably let you hug her/him (joke, programmers with girlfriend - it's a myth). But, what if I want to mirror my start cube by diagonal, but opposite to firstQuadCenter * -1? And I'm sure this will look messy for 3D. However, this code is still pretty robust for 2D. I think this solution is better than the first one, but not the "best practice".

Solution 3 - Dizzy rotation

This solution came to me when I remembered my math lessons about sines and cosines. We can rotate that stuff from 0 to 360 degrees and functions will change their sign.

The code of the solution

 public void Split ()
 {
     Vector3 nodeBoundsExtents = NodeBounds.extents;
     float nodeBoundsExtentsX = nodeBoundsExtents.x;
     float nodeBoundsExtentsZ = nodeBoundsExtents.z;
    
     Vector3 childBoundsSize = new Vector3(nodeBoundsExtentsX, 0, nodeBoundsExtentsZ);
     Vector3 childBoundExtents = childBoundsSize / 2.0f;
     Vector3 nodeCenterPosition = NodeBounds.center;
  
     Vector3 firstQuadCenter = new Vector3(nodeCenterPosition.x, 0, nodeCenterPosition.z) - childBoundExtents;
  
     float[] rotateAngles =
     {
         0.0f,
         90.0f,
         180.0f,
         270.0f
     };
  
     Vector3 rotationDirection = firstQuadCenter - nodeCenterPosition;
  
     foreach (float rotateAngle in rotateAngles)
     {
         Vector3 rotatedDirection = Quaternion.Euler(new Vector3(0.0f, rotateAngle, 0.0f)) * rotationDirection;
      
         CreateChild(rotatedDirection + nodeCenterPosition, childBoundsSize);
     }
 }
  
 private void CreateChild (Vector3 centerOfTheNewChild, Vector3 childBoundsSize)
 {
     GameObject child = new GameObject();
     BoxCollider boxTest = child.AddComponent<BoxCollider>();
     boxTest.size = childBoundsSize;
     child.transform.position = centerOfTheNewChild;
 }

Smart? - Maybe. Simple? - not really. I believe this is the most uncomfortable and complicated-to-understand solution. Without any comment or image, it is hard to understand why we need to rotate something and where we do this rotation. I don't want to have this code, not in this form at least.

The algorithm of this solution is quite simple - we just rotate the first small quad's center around the big quad's center clockwise (also we can do counterclockwise move). We rotate it with step 90. And here we can find a big disadvantage of this solution - it can be used effectively only for quad, not for the rectangle (every rectangle will have other rotation step value).

Conclusion

So, that's all from my side. I have no more solutions and can't imagine anything new for now. I'm pretty sure that there is a formula or two, that will resolve this geometry problem with 2 lines of robust code. I will be very happy if you will share your solutions or comments for my and we will find the best solution sooner or later. Or a smart guy will glance on this thread and just say "But we already have the function GameObject.SplitQuadOn4Parts(), check the documentation".

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

Answer by andrew-lukasik · Apr 29, 2021 at 04:47 PM


You were almost there, partner.


alt text


 using UnityEngine;
 public class SplitAVolume : MonoBehaviour
 {
     [SerializeField] Vector3 _size = new Vector3{ x=2 , y=1 , z=6 };
     void OnDrawGizmos ()
     {
         Split( Vector3.Scale(transform.localScale,_size) , out var a , out var b , out var c , out var d );
         
         Gizmos.matrix = Matrix4x4.TRS( transform.position , transform.rotation , Vector3.one );
         Gizmos.DrawWireCube( a.center , a.size );
         Gizmos.DrawWireCube( b.center , b.size );
         Gizmos.DrawWireCube( c.center , c.size );
         Gizmos.DrawWireCube( d.center , d.size );
     }
     void Start ()
     {
         Split( Vector3.Scale(transform.localScale,_size) , out var A , out var B , out var C , out var D );
         var position = transform.position;
         var rotation = transform.rotation;
         CreateBoxCollider( position + rotation*A.center , rotation , A.size );
         CreateBoxCollider( position + rotation*B.center , rotation , B.size );
         CreateBoxCollider( position + rotation*C.center , rotation , C.size );
         CreateBoxCollider( position + rotation*D.center , rotation , D.size );
     }
     public void Split ( in Vector3 volume , out Bounds A , out Bounds B , out Bounds C , out Bounds D  )
     {
         Vector3 newSize = Vector3.Scale( volume , new Vector3{ x=0.5f , y=1 , z=0.5f } );
         Vector3 newExtent = newSize * 0.5f;
         A = new Bounds( new Vector3{ x=-newExtent.x , z=-newExtent.z } , newSize );
         B = new Bounds( new Vector3{ x=-newExtent.x , z=newExtent.z } , newSize );
         C = new Bounds( new Vector3{ x=newExtent.x , z=newExtent.z } , newSize );
         D = new Bounds( new Vector3{ x=newExtent.x , z=-newExtent.z } , newSize );
     }
     BoxCollider CreateBoxCollider ( Vector3 position , Quaternion rotation , Vector3 size )
     {
         var component = new GameObject("box collider").AddComponent<BoxCollider>();
         component.size = size;
         component.transform.position = position;
         component.transform.rotation = rotation;
         return component;
     }
 }


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.

Follow this Question

Answers Answers and Comments

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

A fast triangle triangle intersection algorithm for unity? 4 Answers

How to Move Vertices from a Mesh to a Specific Location 2 Answers

Multiple Cars not working 1 Answer

Subdivide Bezier Curves 3 Answers

Drawing a Mandelbrot Set problem 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