Re: Applying 4x4 transformation to 3-element vector with numpy

2013-10-09 Thread John Nagle
On 10/8/2013 10:36 PM, Christian Gollwitzer wrote:
 Dear John,
 
 Am 09.10.13 07:28, schrieb John Nagle:
 This is the basic transformation of 3D graphics.  Take
 a 3D point, make it 4D by adding a 1 on the end, multiply
 by a transformation matrix to get a new 4-element vector,
 discard the last element.

 Is there some way to do that in numpy without
 adding the extra element and then discarding it?

 
 if you can discard the last element, the matrix has a special structure:
 It is an affine transform, where the last row is unity, and it can be
 rewritten as
 
 A*x+b
 
 where A is the 3x3 upper left submatrix and b is the column vector. You
 can do this by simple slicing - with C as the 4x4 matrix it is something
 like
 
 dot(C[0:3, 0:3], x) + C[3, 0:3]
 
 (untested, you need to check if I got the indices right)
 
 *IF* however, your transform is perspective, then this is incorrect -
 you must divide the result vector by the last element before discarding
 it, if it is a 3D-point. For a 3D-vector (enhanced by a 0) you might
 still find a shortcut.

I only need affine transformations.  This is just moving
the coordinate system of a point, not perspective rendering.
I have to do this for a lot of points, and I'm hoping numpy
has some way to do this without generating extra garbage on the
way in and the way out.

I've done this before in C++.

John Nagle


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Applying 4x4 transformation to 3-element vector with numpy

2013-10-09 Thread Nobody
On Tue, 08 Oct 2013 23:10:16 -0700, John Nagle wrote:

 I only need affine transformations.  This is just moving
 the coordinate system of a point, not perspective rendering. I have to do
 this for a lot of points, and I'm hoping numpy has some way to do this
 without generating extra garbage on the way in and the way out.

In which case, Christian's answer is correct.

For an affine transformation, the bottom row of the 4x4 matrix will be
[0 0 0 1], so you have:

[x']   [a b c d] [x]   [ax+by+cz+d]
[y'] = [e f g h] [y] = [ex+fy+gz+h]
[z']   [i j k l] [z]   [ix+jy+kz+l]
[1 ]   [0 0 0 1] [1]   [1 ]

 = 

[x']   [ax+by+cz+d]   [a b c] [x]   [d]
[y'] = [ex+fy+gz+h] = [e f g] [y] + [h]
[z']   [ix+jy+kz+l]   [i j k] [z]   [l]

IOW:
xyz_ = m[:3,:3] * xyz + m[:3,3:]

(where xyz is a column vector or 3xN array)


-- 
https://mail.python.org/mailman/listinfo/python-list


Applying 4x4 transformation to 3-element vector with numpy

2013-10-08 Thread John Nagle
   This is the basic transformation of 3D graphics.  Take
a 3D point, make it 4D by adding a 1 on the end, multiply
by a transformation matrix to get a new 4-element vector,
discard the last element.

   Is there some way to do that in numpy without
adding the extra element and then discarding it?

John Nagle
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Applying 4x4 transformation to 3-element vector with numpy

2013-10-08 Thread Christian Gollwitzer

Dear John,

Am 09.10.13 07:28, schrieb John Nagle:

This is the basic transformation of 3D graphics.  Take
a 3D point, make it 4D by adding a 1 on the end, multiply
by a transformation matrix to get a new 4-element vector,
discard the last element.

Is there some way to do that in numpy without
adding the extra element and then discarding it?



if you can discard the last element, the matrix has a special structure: 
It is an affine transform, where the last row is unity, and it can be 
rewritten as


A*x+b

where A is the 3x3 upper left submatrix and b is the column vector. You 
can do this by simple slicing - with C as the 4x4 matrix it is something 
like


dot(C[0:3, 0:3], x) + C[3, 0:3]

(untested, you need to check if I got the indices right)

*IF* however, your transform is perspective, then this is incorrect - 
you must divide the result vector by the last element before discarding 
it, if it is a 3D-point. For a 3D-vector (enhanced by a 0) you might 
still find a shortcut.


Christian
--
https://mail.python.org/mailman/listinfo/python-list