Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 miketucker · Dec 13, 2011 at 03:56 PM · mathvectornormalized

Math Optimization: Normalize

I am creating magnets with a positive and negative charge. This script takes the position of the positive and negative magnets and applies the force to a vector. This occurs each frame on many objects, and is fairly heavy. Anyone have any tips on optimizing it?

 var vector:Vector2 = transform.position;

 var dist1:Vector2 = vector - positivePosition;
 var dist2:Vector2 = negativePosition - vector;
 var div1:float = dist1.magnitude/10;
 var div2:float = dist2.magnitude/10;
 dist1.Normalize();
 dist2.Normalize();
 dist1 /= div1;
 dist2 /= div2;
 vector += dist1 + dist2;

thank you in advance, mike

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 Fattie · Dec 13, 2011 at 07:25 PM 0
Share

Hi $$anonymous$$ike, I may completely misunderstand you, but wouldn't it just be basically: apply this force: (positivePosition-negativePosition) * f where "f" is a small number like 0.1 (just tune it until the result looks O$$anonymous$$). (I guess, you would apply that to both objects - if they are both sliding around.) When you say many objects, how many specifically? And do you mean your many objects "all affect each other" OR do you mean one central object, affects each of your many objects?

2 Replies

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

Answer by Peter G · Dec 13, 2011 at 08:15 PM

First, let me say those aren't real complex operations so this might not be as big a deal as you think. But if you are concerned with speed, here's a faster way of writing it that actually saves two square root operations:

 given vector v;
 magnitude = |v|

 normalized vector = v / |v|
 div = |v|/10

 final = norm / div =  (v / |v|) / (|v| / 10)
 simplified = 10v / |v|^2

Now why is that useful. It happens that the square of the magnitude is cheaper to find than the actual magnitude because we don't have to take the square root at the end. Its just x^2 + y^2.

Hence:

 var dist1:Vector2 = vector - positivePosition;
 dist1 = 10 * dist1 / dist1.sqrMagnitude;

And that's your simplified equation and that might be several times faster than your original equation.

Comment
Add comment · Show 6 · 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 13, 2011 at 10:27 PM 0
Share

Correct simplification of the above code ;).

I've searched around a bit and found that useful summary about square-root implementations

Just to have a reference how much heavier the usual FPU squareroot is, see this WP-article about the "fast inverse square root" algorithm which is also in the ti$$anonymous$$g table. Note that this algorithm uses 4 float multiplications, 1 integer subtraction, 1 float subtraction and one bit shift and it's still around 6 times faster. If you compare a (FPU) float multiplication with a (FPU) square root the multiplication would be around 40 times faster than the square root ;)

If you can, avoid square roots ;)

+1

avatar image Peter G · Dec 14, 2011 at 01:52 PM 0
Share

Interesting links.

I saw a forum thread a few years ago where guys went through and found that they could beat the speed of many of the $$anonymous$$athf functions by writing their own. $$anonymous$$any of those functions ended up on the wiki, but I don't know if they all did and it was some interesting discussion.

avatar image Wolfram · Feb 21, 2012 at 10:43 AM 0
Share

I ran some benchmarks a while ago using the various alternatives (magnitude, Distance, Dot(), ...) and I found that a) for the distance between two vectors, Vector3.Distance(a,b) is fastest. b) for the length of a vector, actually the "manual" version $$anonymous$$athf.Sqrt(a.x*a.x+a.y*a.y+a.z*a.z) is fastest. Which means in your case, |v|^2=v.x*v.x+v.y*v.y+v.z*v.z is the fastest method. But the difference between all variants is usually marginal. I seem to remember it was about 5% faster than v.sqr$$anonymous$$agnitude. @Bunny83: I had a look at that a whiile ago, but I was unable to reproduce it for managed code such as C#. Is there a way to do pointer cast/access in Unity's C#?

avatar image Bunny83 · Feb 21, 2012 at 12:38 PM 0
Share

@Wolfram: Well i didn't run any benchmark or performance tests in managed code yet, but i would say the "manual" version should be the fastest in most cases.

That's how the Vector3 stuff works internally:

 public static float Distance(Vector3 a, Vector3 b)
 {
     Vector3 vector = new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
     return $$anonymous$$athf.Sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);
 }
 
 public static float $$anonymous$$agnitude(Vector3 a)
 {
     return $$anonymous$$athf.Sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
 }
 
 public static float Sqr$$anonymous$$agnitude(Vector3 a)
 {
     return a.x * a.x + a.y * a.y + a.z * a.z;
 }
 
 public static float Dot(Vector3 lhs, Vector3 rhs)
 {
     return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
 }
 
avatar image Wolfram · Feb 21, 2012 at 01:33 PM 0
Share

@Bunny83: I meant the "fast inverse square root" - is there a way to do pointer arithmetics and casts with Unity's C#?

Show more comments
avatar image
0

Answer by uway · Dec 21, 2017 at 02:05 PM

Without unsafe context you can use this implementation of normalizing vector with fast inverse square root:

     //Union used by InvSqrt
     [StructLayout(LayoutKind.Explicit)]
     struct FloatIntUnion
     {
         [FieldOffset(0)]
         public float x;
 
         [FieldOffset(0)]
         public int i;
     }
 
     FloatIntUnion union = new FloatIntUnion();
 
     //Fast inverse Sqrt
     float InvSqrt(float x)
     {
         union.x = x;
         union.i = 0x5f3759df - (union.i >> 1);
         x = union.x;
         x = x * (1.5f - 0.5f * x * x * x);
         return x;
     }
 
 
     //Normalize vector using fast inverse Sqrt
     Vector3 FastNormalized(Vector3 src)
     {
         float inversedMagnitude = InvSqrt(src.sqrMagnitude);
         return src * inversedMagnitude;
     }
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

7 People are following this question.

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

Related Questions

CharacterController on Moving Surface 4 Answers

Move Vectors as curve towards Target 1 Answer

How to get a vector3 (postion) 1 unit away from another in the direction of a 3rd vector3? 2 Answers

Given a point, a "radius" and an arc, how do I find the resulting point? 1 Answer

Unity is a Left-Handed Coordinate System? Why? 5 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