1

I am trying to perform operations on specific elements within a 3d array in python. Here is an example of the array:

[[[   0.5         0.5        50.      ]
  [  50.5        50.5       100.      ]
  [   0.5       100.5        50.      ]
  [ 135.         90.         45.      ]]

 [[  50.5        50.5       100.      ]
  [ 100.5         0.5        50.      ]
  [ 100.5       100.5        50.      ]
  [  45.         90.         45.      ]]

 [[ 100.5       100.5        50.      ]
  [ 100.5       100.5         0.      ]
  [   0.5       100.5        50.      ]
  [  90.          0.         90.      ]]

An example of what I need to to is take the three values seen in the array i.e. 0.5, 0.5, 50. and take the first element from the 4th row i.e. 135. and send those four elements into a function. the function then returns new values for the 3 elements which need to be put into the array.

I am quite new to python so I'm having trouble getting it to work. Should I be making a loop? or something else?

Thanks Nick

An attempt at a solution:

b = shape(a)
triangles = b[0]

for k in range(0,triangles):
    for i in range(0,2):
        a[k,i,:] = VectMath.rotate_x(a[k,i,0],a[k,i,1],a[k,i,2],a[k,3,2])
3
  • 1
    Your attempted solution looks fine. Does it work? Commented Jul 26, 2013 at 1:23
  • It seems to so far, I just didn't know if it is the best way to do it Commented Jul 26, 2013 at 1:51
  • If it seems to work, I'd just keep what you have since you understand it. If you do find that performance is an issue, then you may find that using numpy helps (for example, you could rotate all of your triangles in one line rather than looping over them). Commented Jul 26, 2013 at 2:43

1 Answer 1

1

You can make your VectMath.rotate_x function to rotate an array of vector, then by using slice to get & put data in a:

a = np.array(
[[[   0.5,         0.5,       50.,      ],
  [  50.5,        50.5,      100.,      ],
  [   0.5,       100.5,       50.,      ],
  [ 135. ,        90. ,       45.,      ]],
 [[  50.5,        50.5,      100.,      ],
  [ 100.5,         0.5,       50.,      ],
  [ 100.5,       100.5,       50.,      ],
  [  45. ,        90. ,       45.,      ]],
 [[ 100.5,       100.5,       50.,      ],
  [ 100.5,       100.5,        0.,      ],
  [   0.5,       100.5,       50.,      ],
  [  90. ,         0. ,       90.,      ]]])

def rotate_x(v, deg):
    r = np.deg2rad(deg)
    c = np.cos(r)
    s = np.sin(r)
    m = np.array([[1, 0, 0],
                  [0, c,-s],
                  [0, s, c]])
    return np.dot(m, v)

vectors = a[:, :-1, :]
angles = a[:, -1, 0]

for i, (vec, angle) in enumerate(zip(vectors, angles)):
    vec_rx = rotate_x(vec.T, angle).T
    a[i, :-1, :] = vec_rx

print a 

output:

[[[  5.00000000e-01  -3.57088924e+01  -3.50017857e+01]
  [  5.05000000e+01  -1.06419571e+02  -3.50017857e+01]
  [  5.00000000e-01  -1.06419571e+02   3.57088924e+01]
  [  1.35000000e+02   9.00000000e+01   4.50000000e+01]]

 [[  5.05000000e+01  -3.50017857e+01   1.06419571e+02]
  [  1.00500000e+02  -3.50017857e+01   3.57088924e+01]
  [  1.00500000e+02   3.57088924e+01   1.06419571e+02]
  [  4.50000000e+01   9.00000000e+01   4.50000000e+01]]

 [[  1.00500000e+02  -5.00000000e+01   1.00500000e+02]
  [  1.00500000e+02   6.15385017e-15   1.00500000e+02]
  [  5.00000000e-01  -5.00000000e+01   1.00500000e+02]
  [  9.00000000e+01   0.00000000e+00   9.00000000e+01]]]

If there are many triangle, it maybe faster if we can rotate all the vectors without python for loop.

Here I do the rotate calculation by expand the matrix product:

x' = x
y' = cos(t)*y - sin(t)*z
z' = sin(t)*y + cos(t)*z

So we can vectorize these formulas:

a2 = np.array(
[[[   0.5,         0.5,       50.,      ],
  [  50.5,        50.5,      100.,      ],
  [   0.5,       100.5,       50.,      ],
  [ 135. ,        90. ,       45.,      ]],
 [[  50.5,        50.5,      100.,      ],
  [ 100.5,         0.5,       50.,      ],
  [ 100.5,       100.5,       50.,      ],
  [  45. ,        90. ,       45.,      ]],
 [[ 100.5,       100.5,       50.,      ],
  [ 100.5,       100.5,        0.,      ],
  [   0.5,       100.5,       50.,      ],
  [  90. ,         0. ,       90.,      ]]])

vectors = a2[:, :-1, :]
angles = a2[:, -1:, 0]

def rotate_x_batch(vectors, angles):
    rad = np.deg2rad(angles)
    c = np.cos(rad)
    s = np.sin(rad)
    x = vectors[:, :, 0]
    y = vectors[:, :, 1]
    z = vectors[:, :, 2]
    yr = c*y - s*z
    zr = s*y + c*z
    vectors[:, :, 1] = yr
    vectors[:, :, 2] = zr

rotate_x_batch(vectors, angles)
print np.allclose(a, a2)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.