I have a 3d dynamic node with speed & acceleration vectors. It has maximum speed (magnitude) and minimum speed such as if it exceeds maximum or goes below minimum, it stops accelerating and the speed is set to the respective maximum or minimum.

I have no problem detecting the maximum, I just have to check if the magnitude of speed vector is superior to the maximum.

But I am struggling for the minimum detection, magnitudes being in the positive field it seems to me more tricky. For example I want a minimum speed near 0, or 0, the object is decelerating, at one point it will pass through 0 and start accelerating following acceleration vector.

For example speed magnitude could be as such through frames: 5, 4, 2, 1, 3, 6 .. etc

There is no way to know if it did pass through zero, it could have well passed over zero between 2 and 1 and accelerate after, or between any other number.

Each frame I have these data: last speed vector, actual speed vector, acceleration vector.

How can I detect that next frame I'll cross my minimum value (zero in that example) ?

  • \$\begingroup\$ Wha's the problem with if (acceleration < 0 && magnitude < abs(acceleration)) do stuff? \$\endgroup\$ – Bálint Apr 17 '18 at 21:31
  • \$\begingroup\$ what is 'acceleration' ? It can either be a 3d vector or its magnitude (positive). \$\endgroup\$ – user2591935 Apr 17 '18 at 21:36
  • \$\begingroup\$ it's the magnitude. \$\endgroup\$ – Bálint Apr 17 '18 at 21:43
  • \$\begingroup\$ Then there is no point to check if its below zero because it's always positive. \$\endgroup\$ – user2591935 Apr 17 '18 at 21:46
  • 1
    \$\begingroup\$ Then, if the component of v parallel to a changes signs, that component has gone through zero, and the minimum difference of the speed from zero is the component of v perpendicular to a (which is constant throughout). (Of course, if they are exactly parallel, then the speed actually goes through exactly zero.) \$\endgroup\$ – tom10 Apr 18 '18 at 14:11

Check if the dot product of the acceleration is less, than 0, if it is, check if the acceleration's magnitude is larger, than the magnitude of the velocity. If both of these are true, then it will change direction the next frame.


Using tom10's idea, here is the solution I came up with for minimum detection when speed variation switches:

int speedCheck(bool variationSwitch, float& speed, float minThSpeed, float minSpeed, float maxSpeed) {
    // if change in speed variation ( decrease to minimum and increase again )
    if (variationSwitch) {
        // check if the theorical minimum speed that has been crossed is inferior to set up minimum speed
        if (minThSpeed <= minSpeed) {
            speed = minSpeed;
            return 3;
    else if (speed < minSpeed) {
        speed = minSpeed;
        return 2;
    else if (speed > maxSpeed) {
        speed = maxSpeed;
        return 1;

    return 0;

With variationSwitch calculated by checking the signs of dot products of speed & acceleration before and after applying acceleration:

lastParallelComponent = glm::dot(acceleration, lastSpeed); 

speed += acceleration;

parallelComponent = glm::dot(acceleration, speed);

variationSwitch = lastParallelComponent * parallelComponent < 0.0f;

The theorical minimum speed, minThSpeed can be estimated with perpendicular component of speed over acceleration but I wasn't convinced about its accuracy so instead I calculated it using equations:

float get3DMinSpeed(Vector3f acceleration, Vector3f lastSpeed) {
    // t² * a + t*b + c = |v(t)|²

    float a = glm::dot(acceleration, acceleration);
    float b = 2 * glm::dot(acceleration, lastSpeed);
    float c = glm::dot(lastSpeed, lastSpeed);
    float t = -b / (2 * a);

    float min = (t*t)*a + t * b + c;
    float epsilon = 0.001f;

    if (min > 0.0f + epsilon)
        return sqrt(min);
        return 0.0f;

So minThSpeedcan be updated with that function each time a new acceleration is set up.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.