Calculate next position and velocity after "bounce" Intro and code

I have the following function that calculates an object's "next" position and velocity (in 1 dimension) given a boundary [0, max].

public TwoVector&lt;Double&gt; getNextPositionAndVelocity(double position, double velocity, double max) {
    if (position + velocity &lt; 0) {
        return TwoVector.&lt;Double&gt;builder()
                .x(Math.abs(position + velocity))
                .y(Math.abs(velocity))
                .build();
    }
    if (position + velocity &gt; max) {
        return TwoVector.&lt;Double&gt;builder()
                .x(max - ((position + velocity) % max))
                .y(-Math.abs(velocity))
                .build();
    }
    return TwoVector.&lt;Double&gt;builder()
            .x(position + velocity)
            .y(velocity)
            .build();
}


Explanation


The first condition checks if adding the current velocity to the current position would cause the object to be beyond the "left" boundary.  If that's the case, the next position should be equal to the amount the object would be beyond the left boundary added to the left boundary and the next velocity should point the object to the "right".
The second condition checks if adding the current velocity to the current position would cause the object to beyond the "right" boundary.  If that's the case, the next position should be equal to the amount the object would be beyond the boundary subtracted from the boundary and the next velocity should point the object to the "left".
If neither condition is true, we can add the current velocity to the current position to get the next position without issue.


Question

Are there more straightforward functions to calculate each of these "next" values?  Perhaps a function that "collapses" these branches?
Review


You have redundant code. Store position + velocity in a variable.
Use well-known variable names when the code is of a mathematical nature. Distance x Velocity v A clamped area [a,b].
It is not clear from your description what should happen if the distance is so far away from the boundaries, that when reflecting the movement you are still out of bounds, but on the other side.
.x(max - ((position + velocity) % max)) This does not correspond to your description of 


  the next position should be equal to the amount the object would be beyond the boundary subtracted from the boundary



Proposed Solution


Use mathematical variable names.
Allow damped bouncing when the distance is too far out of bounds (Damped bouncing reflects the value x, alternating around the boundaries until it is clamped with the area [a,b]).
Make both 0 and max a variable, respectively a and b.




public TwoVector&lt;Double&gt; getNextPositionAndVelocity(double x, double v, double a, double b)
{
    assert a &lt; b;
    double xn = x + v;

    // the loop allows for damped bouncing
    while (true) {
        if (xn &lt; a) {
            xn = a - xn;
            v = Math.abs(v);
        }
        else if (xn &gt; b) {
            xn = b - (xn - b);
            v = -Math.abs(v);
        }
        else {
            break;
        }
    }

    return TwoVector.&lt;Double&gt;builder().x(xn).y(v).build();
}