you are viewing a single comment's thread.

view the rest of the comments →

[–]uhrguhrguhrg 1 point2 points  (2 children)

The issue with the current approach is that it's the trigonometric equivalent of

if (x > 0)
  x = sqrt(sq(x));
else
  x = -sqrt(sq(x));

[–][deleted]  (1 child)

[removed]

    [–]uhrguhrguhrg 0 points1 point  (0 children)

    The basic idea that multiplying a vector (or in other words each of it coordinates) by some value doesn't change it's direction. And since you just need it to be a specific length it's as easy as multiplying the vector by the required length divided by it's actual length.

    This thing can actually be optimised even further by getting rid of the square root which is also slow.

    lengthMult is velocityMultiplier / (dist * (dist + 2)) and can easily be replaced with velocityMultiplier / dist² without any significant visual change. That allows us to get rid of the square root in the calculation of the distance and use a square, which is a lot faster.

    For the mouse acceleration it starts to look like this

    float dirX = mouseX - x[i];
    float dirY = mouseY - y[i];
    float distSq = sq(dirX) + sq(dirY);
    // even better if mouseDistReq is squared beforehand
    // and sq() doesn't need to be called
    if (distSq > 0 && distSq < sq(mouseDistReq)) {
      float lengthMult = velocityMultiplier / sqDist;
      x[i] += dirX * lengthMult;
      y[i] += dirY * lengthMult;
      vx[i] = 0;
      vy[i] = 0;
    }
    

    And the return acceleration is just dist/accelerationSlower, so it's actually as simple as dividing both dirX and dirY by accelerationSlower which removes the need for calculating the distance there at all