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 Rabwin · Jul 14, 2013 at 08:08 PM · vector3quaterniondirectionsnap

Snap a direction vector

I have a vector3 direction (target.position - transform.position) which I'd like to snap along the y-axis to 8 directions so that it can be any direction x and z, but be snapped to the nearest 45 degrees on the y.

I've tried many different things like converting the vector to a quaternion, then to a euler, and trying to snap those values and putting them back into a vector but getting half working results. Trying to snap the quaternion itself instead of converting it to euler angles, but getting strange results that snap correctly at certain angles and completely go off in a different direction on other angles.

I'm pretty bad at math so I'd like to at least know the correct way to do this, and if you're feeling generous, some pseudocode as well.

Here are the few things I've tried

  1. Find the angle between the direction and down vector (0,-1,0)

  2. Check if that angle is closer to 0 or 45 (angle % 45 == closer to 0 or 45) (this works correctly so far using two if statements)

  3. Attempt to rotate the Vector3. "snappedDirection = Quaternion.AngleAxis(angle % 45, Vector3.up) * originalDirection;"

Attempt being the keyword here. This only half works, and I could probably get it working if I had some help understanding the correct way to use Quaternions to rotate vectors.

  1. Convert direction to Quaternion using LookRotation, then convert to Euler.

  2. Snap those Euler angles using same method.

  3. Convert back to to Quaternion, then multiply by Vector3 axis used during LookRotation (up vector) This one works on one side, but not the other, and probably won't ever work the way I'm doing it since I lose data when compressing the Quaternion into a Euler or something like that.

I've been stuck on this for over two days and am in a rut, getting frustrated here. Any help at all would be greatly appreciated, thanks!

Edit: Here is code of the first attempt I described above. It doesn't work properly but should show what I'm trying to achieve.

 float num = Vector3.Angle(oDirection, Vector3.up);
 
 float snapAngle = 360 / angles;
 if (num % snapAngle > 0 && num % snapAngle < snapAngle / 2)
 {
     newDirection = Quaternion.AngleAxis(num % snapAngle, Vector3.up) * oDirection;
 }
 else if (num % snapAngle < snapAngle && num % snapAngle > snapAngle / 2)
 {
     newDirection = Quaternion.AngleAxis(snapAngle - (num % snapAngle), Vector3.up) * oDirection;
 }

Basically I have an "explosion" that sends force, but I want to limit that force vertically so that the objects would only receive force at an angle of 0/45/90/.../315 degrees. However the objects should still be pushed sideways at any angle. Please refer to my crude drawings.

alt text

snapangles.jpg (108.0 kB)
Comment
Add comment · Show 3
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 robertbu · Jul 14, 2013 at 10:22 PM 0
Share

I'll be glad to help if you can explain more about the problem. A drawing would help. When you say "snapped to the nearest45 degrees on the y" I visualized using the 'y' as an axis and snapping to angles on this axis. But further you say "find the angle between the direction and the down vector", which does not map very well to my understanding. So what world axis is the axis of rotation for the vector?

avatar image nsxdavid · Jul 14, 2013 at 10:52 PM 0
Share

Yeah the question doesn't make much sense. Show some code of what you are doing now.

avatar image Rabwin · Jul 14, 2013 at 11:48 PM 0
Share

I apologize, I have added some of my actual code and an image to hopefully demonstrate my goal.

1 Reply

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

Answer by robertbu · Jul 15, 2013 at 01:29 AM

Here is a SnapTo() methods that snaps the vector to the specified angle. It works by generating the cross product between the direction and Vector3.up to create an axis for rotation. Then it does an AngleAxis rotation to snap the vector to the angle.

 Vector3 SnapTo(Vector3 v3, float snapAngle) {
     float   angle = Vector3.Angle (v3, Vector3.up);
     if (angle < snapAngle / 2.0f)          // Cannot do cross product 
         return Vector3.up * v3.magnitude;  //   with angles 0 & 180
     if (angle > 180.0f - snapAngle / 2.0f)
         return Vector3.down * v3.magnitude;
     
     float t = Mathf.Round(angle / snapAngle);

     float deltaAngle = (t * snapAngle) - angle;
     
     Vector3 axis = Vector3.Cross(Vector3.up, v3);
     Quaternion q = Quaternion.AngleAxis (deltaAngle, axis);
     return q * v3;
 }
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 Rabwin · Jul 15, 2013 at 01:54 PM 0
Share

The cross product for the rotation axis! Oh my god I'm so dumb I can't believe I forgot that already. Looks like the maths units I did have completely gone to waste hahaha!

avatar image ThomasSoto · May 06, 2019 at 09:45 PM 0
Share

Hey Robert, could you take a look at this post? It's based on this answer but with a small tweak that I'm in need of to shift the snap angles.

https://answers.unity.com/questions/1629211/snap-direction-to-angles-shifting.html

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

17 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

Related Questions

Get rotation from a vector direction. 1 Answer

Slerp look at direction not working... 3 Answers

Rotate object based on hit normal + matching camera direction 0 Answers

Quaternion amount/value of rotation? 2 Answers

Setting up point sets for a procedural tree 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