Calculating rotation for object

Hi Folks.

I use some deep learning solution. This solution create on a scene some face mesh (478 feature points of face), it’s look like on the picture

Issue I had:

I don’t understand how to calculate the rotation of a mesh face with good performance.

I used to use a very bad algorithm for calculating angle whith sin, cos, etc… It works, but only in the range from -90° to +90°, but I would like to get full 360° on each axis. How can I get this result?

Each point on the face looks like a Transform with a changing position, the rotation is always 0.

This suggestion may or may not help you immediately, but: Use Quaternions!
They may be trickier to grasp than classic (Euler) angles, but they avoid certain problems and usually the library (e.g. Unity) provides many helpful methods.

Finally if optimization is your goal, evaluate whether you can do your computations in “burst compiled jobs”. That is a somewhat restrictive (e.g. allows no managed datatypes) but highly performant (natively compiled and inherently parallelized) subsystem in Unity for processing data.

By the way, just in case: Make sure you set the positions of the points from some singular external script and do not have one instance of some updating script in each of the points because that can be a bottleneck as well.
There are some assets for pointcloud rendering in the asset store or you can misuse the particle system (have particles with infinite life and no actual simulation/velocity).

Edit: First of all make sure you do identify the performance bottleneck! It’s often unexpected. Pure math is reasonably fast even with SIN and COS etc.
Unity has multiple Profilers for finding performance issues.

Thank you @DragonCoder . I understand what I should use quaternions. Right now I find any solve how calculate rotations with quaternions.

But I haven’t found a solution yet.
Anyway thank you for your message.

UPD:

The main problem is that the rotation range only works correctly from -90 degrees to 90.

And when I turn the camera on its side, the facial points (as in the picture) visually flip to the left (or right, depending on the rotation). Therefore, the current solution begins to produce bugs.

Well you haven’t even described what exactly you need to calculate. What’s the input and the desired output?

On quaternions, there are many tutorials out there. Best to look at a few and then make yourself a sample project where you play around with them. Learning by doing.

Okay. I you show an example.

As you can see in the image, the dots follow the face. In fact, the points simply change their positions.

When I turn the camera I get errors that (see second GIF).

Why is this happening? Because I’m using a triangle solution that looks like this:

    public float GetDegreeOfRotation(Vector2 pointFirst, Vector2 pointSecond, PointOrder pointsOrder)
    {
      if (pointFirst.y.Equals(pointSecond.y))
        return 0;

      (pointFirst, pointSecond) = GetCorrectOrderOfPlace(pointFirst, pointSecond, pointsOrder);
      _circleRadius = Vector2.Distance(pointFirst, pointSecond) / 2;
      CalculateTrianglePoints(pointFirst, pointSecond);
      CalculateTriangleSides();
      _signCoefficientOfRotation = _vectorUnknownAnglePoint == pointFirst ? -1 : 1;
      // α(rad) = arcos(b^2 + c^2 - a^2) / 2bc
      // α(deg) = α(rad) * 180 / PI
      float alphaRadiansNumerator =
        Mathf.Pow(_triangleSideB, 2) + Mathf.Pow(_triangleSideC, 2) - Mathf.Pow(_triangleSideA, 2);
      float alphaRadiansDenominator = 2 * _triangleSideB * _triangleSideC;
      float alphaRadians = Mathf.Acos(alphaRadiansNumerator / alphaRadiansDenominator);
      float alphaDegrees = alphaRadians * _StraightAngle / Mathf.PI;
      float alphaDegreesSigned = alphaDegrees * _signCoefficientOfRotation;
      return alphaDegreesSigned;
    }

This solution wotks good only for half-circle (from -90° to °90).

UPD:
Add used methods

CalculateTrianglePoints

    private void CalculateTrianglePoints(Vector2 pointFirst, Vector2 pointSecond)
    {
      // Calculate the center of the segment between the points
      _circleCenterPoint = new Vector2((pointFirst.x + pointSecond.x) / 2, (pointFirst.y + pointSecond.y) / 2);
      // Depending on the difference in the Y coordinate, we determine a point on a circle with an unknown angle
      _vectorUnknownAnglePoint = pointFirst.y < pointSecond.y ? pointFirst : pointSecond;
      // Defining a point on a circle with a zero angle
      _vectorZeroAnglePoint = _circleCenterPoint;
      _vectorZeroAnglePoint.x = _vectorUnknownAnglePoint != pointFirst
        ? _vectorZeroAnglePoint.x + _circleRadius
        : _vectorZeroAnglePoint.x - _circleRadius;
    }

CalculateTrianglesSides

    /// <summary>
    /// Calculates the length of each side of the triangle. The sides of the length of sides C and B are always equal,
    /// The length of the third side of the triangle is calculated as the point of the vector 0 degrees lying on the
    /// circle <b>minus</b> the point of the vector of an unknown angle lying on the circle
    /// </summary>
    private void CalculateTriangleSides()
    {
      _triangleSideC = _circleRadius;
      _triangleSideB = _circleRadius;
      _triangleSideA = Mathf.Sqrt(Mathf.Pow(_vectorZeroAnglePoint.x - _vectorUnknownAnglePoint.x, 2) +
                                  Mathf.Pow(_vectorZeroAnglePoint.y - _vectorUnknownAnglePoint.y, 2));
    }

9501667--1338331--Jim.gif
9501667--1338337--Ronaldo.gif

SOLVED!

I created another request on this topic and they gave me an answer that helped me a lot.

Guys, if anyone is looking for the same solution, look here: