patternMinor
Manipulating matrices for 3D drawing
Viewed 0 times
drawingformanipulatingmatrices
Problem
I've written a short library for manipulating matrices for 3D drawing. I've tried to strike a balance between speed and readability. Anything to improve?
```
%!
%mat.ps
%Matrix and Vector math routines
/ident { 1 dict begin /n exch def
[
1 1 n { % [ i
[ exch % [ [ i
1 1 n { % [ [ i j
1 index eq { 1 }{ 0 } ifelse % [ [ i b
exch % [ [ b i
} for % [ [ b+ i
pop ] % [ [ b+ ]
} for % [ [b+]+ ]
]
end } def
/rotx { 1 dict begin /t exch def
[ [ 1 0 0 ]
[ 0 t cos t sin neg ]
[ 0 t sin t cos ] ]
end } def
/roty { 1 dict begin /t exch def
[ [ t cos 0 t sin ]
[ 0 1 0 ]
[ t sin neg 0 t cos ] ]
end } def
/rotz { 1 dict begin /t exch def
[ [ t cos t sin neg 0 ]
[ t sin t cos 0 ]
[ 0 0 1 ] ]
end } def
/.error where { pop /signalerror { .error } def } if
/dot { % u v
2 copy length exch length ne {
/dot cvx /undefinedresult signalerror } if
% u v
0 % u v sum
0 1 3 index length 1 sub { % u v sum i
3 index 1 index get exch % u v sum u_i i
3 index exch get % u v sum u_i v_i
mul add % u v sum
} for % u v sum
3 1 roll pop pop % sum
} bind def
% [ x1 x2 x3 ] [ y1 y2 y3 ] cross [ x2y3-y2x3 x3y1-x1y3 x1y2-x2y1 ]
/cross { % u v
dup length 3 ne 2 index length 3 ne or {
/cross cvx /undefinedresult signalerror } if
% u v
exch aload pop 4 3 roll aload pop % x1 x2 x3 y1 y2 y3
[
5 index 2 index mul % ... [ x2*y3
3 index 6 index mul sub % ... [ x2y3-y2x3
5 index 5 index mul % ... [ x2y3-y2x3 x3*y1
8 index 4 index mul sub % ... [ x2y3-y2x3 x3y1-x1y3
8 index 5 index mul % ... [ x2y3-y2x3 x3y1-x1y3 x1*y2
8 index 7 index mul sub % ... [ x2y3-y2x3 x3y1-x1y3 x1y2-x2y1
]
7 1 roll 6 { pop } repeat
} bind def
/transpose { STATICDICT begin
/A exch def
```
%!
%mat.ps
%Matrix and Vector math routines
/ident { 1 dict begin /n exch def
[
1 1 n { % [ i
[ exch % [ [ i
1 1 n { % [ [ i j
1 index eq { 1 }{ 0 } ifelse % [ [ i b
exch % [ [ b i
} for % [ [ b+ i
pop ] % [ [ b+ ]
} for % [ [b+]+ ]
]
end } def
/rotx { 1 dict begin /t exch def
[ [ 1 0 0 ]
[ 0 t cos t sin neg ]
[ 0 t sin t cos ] ]
end } def
/roty { 1 dict begin /t exch def
[ [ t cos 0 t sin ]
[ 0 1 0 ]
[ t sin neg 0 t cos ] ]
end } def
/rotz { 1 dict begin /t exch def
[ [ t cos t sin neg 0 ]
[ t sin t cos 0 ]
[ 0 0 1 ] ]
end } def
/.error where { pop /signalerror { .error } def } if
/dot { % u v
2 copy length exch length ne {
/dot cvx /undefinedresult signalerror } if
% u v
0 % u v sum
0 1 3 index length 1 sub { % u v sum i
3 index 1 index get exch % u v sum u_i i
3 index exch get % u v sum u_i v_i
mul add % u v sum
} for % u v sum
3 1 roll pop pop % sum
} bind def
% [ x1 x2 x3 ] [ y1 y2 y3 ] cross [ x2y3-y2x3 x3y1-x1y3 x1y2-x2y1 ]
/cross { % u v
dup length 3 ne 2 index length 3 ne or {
/cross cvx /undefinedresult signalerror } if
% u v
exch aload pop 4 3 roll aload pop % x1 x2 x3 y1 y2 y3
[
5 index 2 index mul % ... [ x2*y3
3 index 6 index mul sub % ... [ x2y3-y2x3
5 index 5 index mul % ... [ x2y3-y2x3 x3*y1
8 index 4 index mul sub % ... [ x2y3-y2x3 x3y1-x1y3
8 index 5 index mul % ... [ x2y3-y2x3 x3y1-x1y3 x1*y2
8 index 7 index mul sub % ... [ x2y3-y2x3 x3y1-x1y3 x1y2-x2y1
]
7 1 roll 6 { pop } repeat
} bind def
/transpose { STATICDICT begin
/A exch def
Solution
As far as readability goes, maybe you'd like to add an
arg1 arg2 arg3 -- result1 result2 type of comment to each function? So we know what was on the stack before invoking, and what we expect to find afterward? Almost equivalently, you might show a unit test invoking your function and verifying the result.Context
StackExchange Code Review Q#23074, answer score: 3
Revisions (0)
No revisions yet.