Simulating ndgrid function of MATLAB

This might do it, if I understood the MATLAB docs:

ndgrid[args___] /; AllTrue[{args}, VectorQ] :=
  Table[
   With[{aa = {args}[[i]]},
    ArrayPad[#, ReplacePart[{0, Length[#] - 1} & /@ {args}, {i, 2} -> 0], #] &@
     ArrayReshape[aa, ReplacePart[ConstantArray[1, Length@{args}], i -> Length@aa]]
    ],
   {i, Length@{args}}];

xa = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19};
ya = {2, 4, 6, 8, 10, 12};

MatrixForm /@ ndgrid[xa, ya]

Mathematica graphics

MatrixForm /@ ({xx, yy, zz} = ndgrid[{1, 2, 3}, {4, 5}, {6, 7, 8, 9}])

Mathematica graphics

Check with MATLink:

Needs["MATLink`"]
OpenMATLAB[]

MEvaluate["[X,Y,Z]=ndgrid([1 2 3],[4 5],[6 7 8 9])"];
{MGet["X"], MGet["Y"], MGet["Z"]} == {xx, yy, zz}
(*  True  *)

Here's my implementation:

Clear[ndgridx];
ndgridx[a__?VectorQ] := Transpose[Outer[List, a, 1], Range[1 + Length@{a}]~RotateLeft~1]

If you also need 2nd syntax i.e.

[X1,X2,...,Xn] = ndgrid(xg)

then

Clear[ndgridx];
ndgridx /: (lhs_List = ndgridx[a_]) := lhs = ndgridx @@ ConstantArray[a, Length@lhs]
ndgridx /: (lhs_List = ndgridx[a__?VectorQ]) := 
 lhs = Transpose[Outer[List, a, 1], Range[1 + Length@{a}]~RotateLeft~1]

Notice in this case single ndgridx[……] no longer works, it always needs a left hand side that is a List. Test:

{testx, testy} = ndgridx[{1, 2, 4}];

MatrixForm@testx

Mathematica graphics

MatrixForm@testy

Mathematica graphics

range = {min, max} = {-1, 1};

{xm, ym, zm} = ndgridx@Range[min, max, 0.01];

ListDensityPlot3D[Exp[-(xm^2 + zm^2 + ym^2)], DataRange -> {range, range, range}]

Mathematica graphics