Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Rotating Direction with another direction in 3D

Discussion in 'Scripting' started by Cronnoc, Jan 20, 2021.

  1. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    So I'm currently creating an algorithm and I've run into some trouble. I have a direction that I need to rotate based on another direction like so.
    rotate lines.png
    Normally I would simply store the angle between the 2 and rotate the direction by that angle, however, these directions are in 3D and can be pointing in any direction. I can't just add the directions together and normalise it because once the first direction is equal to the second it will stop changing. I don't know how to achieve what I'm trying to do so I request assistance.

    Sorry if I've explained badly but any assistance would be greatly appreciated.
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
  3. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    I would use RotateTowards, but once the first Vector has reached the second, it will stop rotating. I need it to keep rotating by the same amount.
     
  4. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    ok so you want to take the difference between the two and apply it over and over again?

    in that case you want our good old friend Quaternion.FromToRotation:
    Code (CSharp):
    1. // Black line in diagram
    2. Vector3 from;
    3. // Red line in diagram
    4. Vector3 to;
    5. Quaternion diff;
    6.  
    7. Vector3 current;
    8.  
    9. void Start() {
    10.   diff = Quaternion.FromToRotation(from, to);
    11.   current = from;
    12. }
    13.  
    14. void UpdateDirection() {
    15.   current = diff * current;
    16. }
    Every time you call UpdateDirection here, the direction will change by the same angle in the same direction each time.
     
  5. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    Thank you, this was the function I need. I do have another question though.

    Warning there are a lot of uses of the words "difference" and "directions"

    I am creating a trajectory prediction algorithm and I am basically storing several of the object's previous points, then calculating their average direction (the black line). I then need to calculate the average difference between all the directions (the red line) then, finally, I need to calculate the average difference between all the differences in directions.

    Once I have all these I am then applying the average direction to the current location to determine the next predicted point. I then rotate that average direction by the average difference in directions, then finally, I need to rotate the average difference in directions by the average difference in the difference in directions.


    I have the first two steps working. Using the FromToRotation function I have determined the average difference in directions. However, now I am left with a list of Quaternions that represent all the differences in directions. What I need to do is determine the average difference between all those Quaternions and store it in a way that I can rotate another Quaternion by it.

    Here is my current code.
    Code (CSharp):
    1. // Determine average direction
    2. for (int index = obj.PastLocations.Length - 1; index > 0; index--)
    3. {
    4.      avgDirection += (obj.PastLocations[index - 1] - obj.PastLocations[index]).normalized;
    5.      directions.Add((obj.PastLocations[index - 1] - obj.PastLocations[index]).normalized);
    6.      avgDistanceBetweenPoints += Vector3.Distance(obj.PastLocations[index - 1], obj.PastLocations[index]);
    7. }
    8. avgDirection.Normalize();
    9. avgDistanceBetweenPoints /= obj.PastLocations.Length - 1;
    10.  
    11. // Determine average change in direction
    12. Quaternion avgDirectionChange = Quaternion.identity;
    13. List<Quaternion> changesInDirection = new List<Quaternion>();
    14. for (int index = 0; index < directions.Count - 2; index++)
    15. {
    16.      changesInDirection.Add(Quaternion.FromToRotation(directions[index], directions[index + 1]));
    17. }
    18. avgDirectionChange = changesInDirection.Average();
    19.  
    20. // Determine average change in change in direction
    21. Quaternion avgChangeInDirectionChange = Quaternion.identity;
    22. List<Quaternion> changesInChangeInDirection = new List<Quaternion>();
    23. for (int index = 0; index < changesInDirection.Count - 2; index++)
    24. {
    25.      changesInChangeInDirection.Add(changesInDirection[index] *
    26.      Quaternion.Inverse(changesInDirection[index+1]));
    27. }
    28. avgChangeInDirectionChange = changesInChangeInDirection.Average();
    29. avgChangeInChangeInDirection.Normalize();
    30.  
    31. // Calculate trajectory
    32. List<Vector3> points = new List<Vector3>();
    33. points.Add(obj.transform.position);
    34. for (int index = 0; index < 50; index++)
    35. {
    36.      points.Add(points.Last() + (avgDirection * avgDistanceBetweenPoints));
    37.      avgDirection = avgDirectionChange * avgDirection;
    38.      avgDirectionChange = avgChangeInDirectionChange * avgDirectionChange; // This line is the problem. There is either a problem with the rotating of Quaternions or
    39.                                                                                       //the calculation of avgChangeInDirectionChange
    40. }
    Note: I'm pretty confident in the Average() function I'm using to average the Quaternions


    I really do apologise about all the "differences" and "directions" if you need to clarify anything let me know.
     
  6. Cronnoc

    Cronnoc

    Joined:
    Jul 6, 2018
    Posts:
    18
    Sorry for the bump but I'm really struggling here. Let me explain what I'm trying to do. Maybe there is a better way to do it than what I'm trying. I have a collection of points in 3D space. Using these points, I need to predict the following points (number of points should be variable but I don't think that should be relevant). The way I am currently doing this is be calculating the average direction between each of those points, calculating the average difference between those directions (FromToRotations), and the average change between those differences.

    I then need to, starting from the current point, add a new point in the average direction based on the average distance between points. Then I rotate that direction by the average change, then I need to rotate that value by the average change in the changes.

    I have no idea if this image helps or not. Black is average direction, red is all the changes in direction between the points, darker red is the average of those. I honestly don't know if it will help but it is the sort of idea I'm going for.
    lines.png

    I got the first two steps working, I found the average direction (pretty easy), and I am able to rotate that by the average direction (FromToRotation) but I have found no way to calculate the average change or to add it.

    Once again, really sorry for the bump, but I need help.