I'm trying to implement fast voxel traversal algorithm and calculate T and M according to this answer (T is tDelta, M is tMax). All is good if the two components of the direction vector V are positive. But if at least one of them is negative, it's work wrong.
Green point is start, red is end. All seems correct.

And now from bigger to less position.

Traversal method:
private IEnumerable<Vector2> GetCrossedCells(Vector2 pPoint1, Vector2 pPoint2)
{
    Vector2 V = pPoint2 - pPoint1; // direction & distance vector
    if (V != Vector2.Zero)
    {
        Vector2 U = Vector2.Normalize(V); // direction unit vector
        Vector2 S = new Vector2(Math.Sign(U.X), Math.Sign(U.Y)); // sign vector
        Vector2 P = pPoint1; // position
        Vector2 G = new Vector2((int) Math.Floor(P.X / CELL_SIZE), (int) Math.Floor(P.Y / CELL_SIZE)); // grid coord
        Vector2 T = new Vector2(Math.Abs(CELL_SIZE / U.X), Math.Abs(CELL_SIZE / U.Y));
        Vector2 M = new Vector2(
            Single.IsInfinity(T.X) ? Single.PositiveInfinity : T.X * (1.0f - (P.X / CELL_SIZE) % 1),
            Single.IsInfinity(T.Y) ? Single.PositiveInfinity : T.Y * (1.0f - (P.Y / CELL_SIZE) % 1));
        Vector2 D = Vector2.Zero;
        bool isCanMoveByX = S.X != 0;
        bool isCanMoveByY = S.Y != 0;
        while (isCanMoveByX || isCanMoveByY)
        {
            yield return G;
            D = new Vector2(
                S.X > 0 ? (float) (Math.Floor(P.X / CELL_SIZE) + 1) * CELL_SIZE - P.X :
                S.X < 0 ? (float) (Math.Ceiling(P.X / CELL_SIZE) - 1) * CELL_SIZE - P.X :
                0,
                S.Y > 0 ? (float) (Math.Floor(P.Y / CELL_SIZE) + 1) * CELL_SIZE - P.Y :
                S.Y < 0 ? (float) (Math.Ceiling(P.Y / CELL_SIZE) - 1) * CELL_SIZE - P.Y :
                0);
            if (Math.Abs(V.X) <= Math.Abs(D.X))
            {
                D.X = V.X;
                isCanMoveByX = false;
            }
            if (Math.Abs(V.Y) <= Math.Abs(D.Y))
            {
                D.Y = V.Y;
                isCanMoveByY = false;
            }
            if (M.X <= M.Y)
            {
                M.X += T.X;
                G.X += S.X;
                if (isCanMoveByY)
                {
                    D.Y = U.Y / U.X * D.X; // U.X / U.Y = D.X / D.Y => U.X * D.Y = U.Y * D.X
                }
            }
            else
            {
                M.Y += T.Y;
                G.Y += S.Y;
                if (isCanMoveByX)
                {
                    D.X = U.X / U.Y * D.Y;
                }
            }
            V -= D;
            P += D;
        }
    }
}
In debug I can see that for example M.Y > M.X when should be the opposite if S.X < 0 or S.Y < 0.
Tell me please what my code work wrong for negative directions?
