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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
5
Question by NeatWolf · Mar 11, 2014 at 06:00 PM · rotationmobilerotatevector2efficient

What's the most efficient way to rotate a Vector2 of a certain angle around the axis orthogonal to the plane they describe?

Hi UnityAnswers Community,

I am using a Vector2 to store input information(a gesture direction), but I also need to calibrate it (it's an external device) by rotating the input direction around the axis orthogonal to the plane they lay on.

To help you visualize the code:

     Vector2 normalizedDirection;
     float calibrationAmount; //amount of rotation


I searched for a native function to rotate a vector2 but didn't find it. A Google search didn't help either.

Since the code should also run on mobile, what's the most efficient way to do it in C# without using external DLLs? Should I manually do the math?

alt text

At the moment I'm using this code:

     float _x = normalizedDirection.x;
     float _y = normalizedDirection.y;
 
     float _angle = calibrationAmount * Mathf.Deg2Rad;
     float _cos = Mathf.Cos(_angle);
     float _sin = Mathf.Sin (_angle);
 
     float _x2 = _x * _cos - _y * _sin;
     float _y2 = _x * _sin + _y * _cos;
 
     return new Vector2(_x2, _y2);


But I'm not sure it's the best way to do it. It seems overly complicated for a simple rotation on the origin that should be implemented natively.

Do you know a simpler, computationally fastest way to do it?

Thanks for your time :)

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 Jamora · Mar 11, 2014 at 06:44 PM 0
Share

How come this question is marked as wiki twice?

2 Replies

· Add your reply
  • Sort: 
avatar image
11

Answer by DDP · Jun 25, 2014 at 04:12 PM

What about using an extension method?

 using UnityEngine;
 
 public static class Vector2Extension {
     
     public static Vector2 Rotate(this Vector2 v, float degrees) {
         float sin = Mathf.Sin(degrees * Mathf.Deg2Rad);
         float cos = Mathf.Cos(degrees * Mathf.Deg2Rad);
         
         float tx = v.x;
         float ty = v.y;
         v.x = (cos * tx) - (sin * ty);
         v.y = (sin * tx) + (cos * ty);
         return v;
     }
 }

Can be use that way:

 Vector2 direction = Vector2.right.Rotate(45f);


Comment
Add comment · Show 8 · 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 Tabemasu Games · Nov 18, 2014 at 04:14 PM 1
Share

Your method seems good, but it does change the source vector (v) AND return it. To be consistent with other methods (like Clamp$$anonymous$$agnitude), I'd return a new Vector 2 :

 public static class Vector2Extension {
     public static Vector2 Rotate(this Vector2 v, float degrees) {
         float radians = degrees * $$anonymous$$athf.Deg2Rad;
         float sin = $$anonymous$$athf.Sin(radians);
         float cos = $$anonymous$$athf.Cos(radians);
         
         float tx = v.x;
         float ty = v.y;
 
         return new Vector2(cos * tx - sin * ty, sin * tx + cos * ty);
     }
 }
 
avatar image Trexug · Nov 19, 2014 at 12:03 PM 2
Share

@Tabemasu Games Vector2 is a struct (pass by value). $$anonymous$$odifying the parameter is fine, as it does not affect the value provided when calling the method (since there is no ref or out keyword).

avatar image Tabemasu Games · Nov 19, 2014 at 01:02 PM 0
Share

@Trexug I didn't know it was a struct, thanks for the intel. :)

avatar image akauper · Dec 22, 2014 at 09:15 AM 3
Share

Quaternions can do all this math for you:

 public static class Vector2Extension
 {
     public static Vector2 Rotate(this Vector2 v, float degrees)
     {
         return Quaternion.Euler(0, 0, degrees) * v;
     }
 }

This will work the same as above.

avatar image DungDajHjep akauper · Dec 31, 2019 at 09:58 AM 0
Share

thanks @akauper

avatar image XenoRo · Nov 28, 2017 at 08:15 PM 2
Share

@akauper Quaternion can indeed do the math for you, but the question is not "how can I do this?", and context matters. On a low-weight code like this, overhead can make up a large portion of the method's execution time, And doing the math "manually" avoids large chunks of overhead and, at least according to my tests, can make the code be roughly 2 times faster. --- It's already super fast anyway, and optimizing it is overkill for anything but the most hardcore simulation or bullet-hell games, but it's faster none the less, and as an extension method that's probably never getting changed after you implement it once, it's certainly worth doing I$$anonymous$$HO.

Show more comments
avatar image
1

Answer by whydoidoit · Mar 11, 2014 at 06:41 PM

Well if it works don't knock it. You could also do this:

    return Quaternion.AngleAxis(_angle, Vector3.forward) * normalizedDirection;
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 Truthveyor · May 19, 2017 at 08:28 AM 0
Share

I was just looking for an answer like this. Thank you.

Except based on my test, in this example, the answer should be

return Quaternion.AngleAxis(calibrationAmount, -Vector3.forward) * normalizedDirection;

because calibrationAmount is in degrees, and using Vector3.forward will cause it to rotate in the opposite direction, so you want to use -Vector3.forward ins$$anonymous$$d.

avatar image Bunny83 Truthveyor · May 19, 2017 at 09:06 AM 0
Share

That's irrelevant. There is no right way how something should rotate. If anything then the normal mathematical way should apply which is a counter-clockwise rotation and as far as i can tell that's exactly what's happening. If you need the rotation the other way round you have to either:

  • use a negative angle

  • invert the rotation axis (like you did)

But again the "normal" rotation direction is counter-clockwise. $$anonymous$$eep in $$anonymous$$d that Unity is a left-handed system

Though if you only work with 2d vectors the solution that DDP posted is the faster one with less overhead. Creating a quaternion with AngleAxis also requires one "Sin" and one "Cos" call. Though the actual quaternion multiplication is a bit longer since it only works with 3d vectors:

 // for reference this is the multiply operator of the Quaternion struct.
 public static Vector3 operator *(Quaternion rotation, Vector3 point)
 {
     float num = rotation.x * 2f;
     float num2 = rotation.y * 2f;
     float num3 = rotation.z * 2f;
     float num4 = rotation.x * num;
     float num5 = rotation.y * num2;
     float num6 = rotation.z * num3;
     float num7 = rotation.x * num2;
     float num8 = rotation.x * num3;
     float num9 = rotation.y * num3;
     float num10 = rotation.w * num;
     float num11 = rotation.w * num2;
     float num12 = rotation.w * num3;
     Vector3 result;
     result.x = (1f - (num5 + num6)) * point.x + (num7 - num12) * point.y + (num8 + num11) * point.z;
     result.y = (num7 + num12) * point.x + (1f - (num4 + num6)) * point.y + (num9 - num10) * point.z;
     result.z = (num8 - num11) * point.x + (num9 + num10) * point.y + (1f - (num4 + num5)) * point.z;
     return result;
 }


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

28 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

Related Questions

How to rotate a 2D object on touch 1 Answer

Player rotating in direction of joystick doesn't work, why?,Rotate Player in direction of Joystick has too little impact 0 Answers

How to always rotate clockwise 1 Answer

Character to Ground and Turn Rotation 1 Answer

How to get all gameObjects with a script on them 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