Coordinate transformations from a randomly generated normal vector
<p>I'm trying to randomly generate coordinate transformations for a fitting routine I'm writing in python. I want to rotate my data (a bunch of [x,y,z] coordinates) about the origin, ideally using a bunch of randomly generated normal vectors I've already created to define planes -- I just want to shift each plane I've defined so that it lies in the z=0 plane.</p>

<p>Here's a snippet of my code that should take care of things once I have my transformation matrix. I'm just not sure how to get my transformation matrix from my normal vector and if I need something more complicated than numpy for this.</p>

<pre><code>import matplotlib as plt
import numpy as np
import math

origin = np.array([35,35,35])
normal = np.array([np.random.uniform(-1,1),np.random.uniform(-1,1),np.random.uniform(0,1)])
mag = np.sum(np.multiply(normal,normal))
normal = normal/mag

a = normal[0]
b = normal[1]
c = normal[2]

#I know this is not the right transformation matrix but I'm not sure what is...
#Looking for the steps that will take me from the normal vector to this transformation matrix
rotation = np.array([[a, 0, 0], [0, b, 0], [0, 0, c]])

#Here v would be a datapoint I'm trying to shift?
v=(test_x,test_y,test_z)
s = np.subtract(v,origin) #shift points in the plane so that the center of rotation is at the origin
so = np.multiply(rotation,s) #apply the rotation about the origin
vo = np.add(so,origin) #shift again so the origin goes back to the desired center of rotation

x_new = vo[0]
y_new = vo[1]
z_new = vo[2]

fig = plt.figure(figsize=(9,9))
plt3d = fig.gca(projection='3d')
plt3d.scatter(x_new, y_new, z_new, s=50, c='g', edgecolor='none')
</code></pre>

<p>I think you have a wrong concept of rotation matrices. Rotation matrices define rotation of a certain angle and can not have diagonal structure. </p>

<p>If you imagine every rotation as a composition of a rotation around the X axis, then around the Y axis, then around the Z axis, you can build each matrix and compose the final rotation as product of matrices</p>

<pre><code>R = Rz*Ry*Rx
Rotated_item = R*original_item
</code></pre>

<p>or</p>

<pre><code>Rotated_item = np.multiply(R,original_item)
</code></pre>

<p>In this formula Rx is the first applied rotation. 
<br>Be aware that</p>

<ul>
<li>you can obtain your rotation by composing many different set of 3 rotation </li>
<li>the sequence it is not fixed, it could be X-Y-Z or Z-Y-X or Z-X-Z or whatever combination. The values of angles may change as the sequence changes</li>
<li>it is "dangerous" use this matrices for rotation of critical values (90-180-270-360 degrees)</li>
</ul>

<p>How to compose each single rotation matrix around 1 axis? See <a href="https://wikimedia.org/api/rest_v1/media/math/render/svg/a6821937d5031de282a190f75312353c970aa2df" rel="nofollow">this image from wikipedia</a>. Numpy has all things you need. </p>

<p>Now you just have to define 3 angles values.
Of course you can derive 3 angles values from a random normalized vector (a,b,c) as you write in your question, but rotation is a process that transform a vector in another vector. Maybe you have to specify something like
<em>"I want to find the rotation R around the origin that transform (0,0,1) into (a,b,c)".</em> A completely different rotation R' is the one that transform (1,0,0) into (a,b,c). </p>

python 3d coordinate-transformation rotational-matrices