質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

2992閲覧

3次元座標を回転させたい

Lily_1007

総合スコア35

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/07/24 08:56

前提

3次元座標を回転させたいです。
今、一般の左手系のx, y, z座標で様々な粒子の座標が入っています。
(例)
[[13.73374081 -1.31704426 1.06994426]
[13.73374081 0.1249985 -0.34463105]
[13.73374081 0.02886231 0.30085477]
[13.73374081 0.08379728 -0.42703351]
[13.73374081 -0.24581251 0.1772511 ]
[13.73374081 -0.1084751 -0.06995624]
[27.46748161 1.21683085 -0.51630282]
[27.46748161 1.24429834 -0.54377031]
[27.46748161 -0.04667326 0.0605143 ]
[27.46748161 0.99709105 -0.76351017]]

このとき、これらの座標を回転させたいと考えています。
具体的には
[0, 0, 1]というz軸が[ 0.78508819, -0.58677951, -0.19830868]に移動するような回転です。

つまり、どの軸に何度回転させるかという情報がなく、上記のような2つの座標の情報があり、それにともなう回転に対応して、粒子の座標も変換させたいです。

実現したいこと

上記の回転に対応して粒子の座標も回転させたいです。
ネットをさがしてもどれも回転角が分かって居る状態での変換方法だったのでここでお伺いしました。

よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

python3.7

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2022/07/25 01:09 編集

> [0, 0, 1]というz軸が[ 0.78508819, -0.58677951, -0.19830868]に移動するような回転です。 そのような回転は複数考えられますが、すでについている回答のようにその中から適当に一つ選んで良いのですか? 例えば、回転後のz軸が回転前のx軸に重なるような回転は y軸を軸として90度回転する方法と [1,1,1]を軸として120度回す方法や [1,0,1]を軸に180度回すなど無数に考えられます。
fana

2022/07/25 01:41

同じ内容を他の言葉で言い換えると話がわかりやすいかもしれない. 基底変換したいです. 基底ベクトルの1つは与えられています. でもこれだけだとできません.…ていう話. ↓ うん,だったら残りの基底ベクトルを適切に決めればよいだけの話ですよね. で,何が「適切」なのかは外野には不明なので,質問するならばそこのところを説明する必要がある. (まぁ,おそらくこれで良いのだろうけど,っていう決め方が既に回答されている様子だけども)
guest

回答2

0

お使いの言語での効率の良い方法は存じませんので,純粋な計算方法の話に留まりますが…

[0, 0, 1]というz軸が[ 0.78508819, -0.58677951, -0.19830868]に移動するような回転です。

っていうのを,3x3回転行列を用いた変換式に愚直に突っ込んでみればわかりやすいでしょう.

[r11 r12 r13][0] [0.785...] [r21 r22 r23][0] = [-0.58...] [r31 r32 r33][1] [-0.19...]

[ 0.78508819, -0.58677951, -0.19830868]

というのを,{r13, r23, r33} の値にそのまま用いれば良いことが明確ですね.

で,同様に,
その回転で「xはどこに行けば良いのか」あるいは「Yはどこに行けばよいのか」のどちらかを定めて,全く同じことをしてみれば,また回転マトリクスの対応する箇所の要素の値が埋まりますね.

そしたらもう回転マトリクスの意味的に残りの要素は定まる(そこにはもう自由度はない)ので,それで終了です.
(「回転角」とか陽に考える必要はないです.)

質問文にはZの話しか出てきていないので「XやYについてどうなれば良いのか?」が不明ですが,きっと問題の背景事情的にはそこら辺の話は定まるのでしょうから,それに基づいて求めればよいです.

投稿2022/07/25 02:04

編集2022/07/25 02:04
fana

総合スコア11652

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/07/25 02:17

ものすごくざっくり言うと,回転マトリクスってのは 「(0 0 1), (0 1 0), (0 0 1) が回転後にはどこに行けば良いんですかね?」っていう値を並べたもの. ※縦横を変えて読めば, 「回転したら (0 0 1), (0 1 0), (0 0 1) になるやつってのは,回転前はどこなんですかね?」っていう値を並べたもの.
Lily_1007

2022/07/25 04:04

ありがとうございます。実際に回転行列のコードも作成してみました。
guest

0

ベストアンサー

scipy.spatial.transform.Rotation を使う場合。

python

1import numpy as np 2import numpy.linalg as LA 3from scipy.spatial.transform import Rotation as R 4 5particles = np.array([ 6 [13.73374081, -1.31704426, 1.06994426], 7 [13.73374081, 0.1249985, -0.34463105], 8 [13.73374081, 0.02886231, 0.30085477], 9 [13.73374081, 0.08379728, -0.42703351], 10 [13.73374081, -0.24581251, 0.1772511,], 11 [13.73374081, -0.1084751, -0.06995624], 12 [27.46748161, 1.21683085, -0.51630282], 13 [27.46748161, 1.24429834, -0.54377031], 14 [27.46748161, -0.04667326, 0.0605143,], 15 [27.46748161, 0.99709105, -0.76351017], 16]) 17z_axis = [0, 0, 1] 18p = [0.78508819, -0.58677951, -0.19830868] 19 20# normal vector 21axis = np.cross(z_axis, p) 22axis = axis / LA.norm(axis) 23 24# angle 25inner = np.inner(z_axis, p) 26norms = LA.norm(z_axis) * LA.norm(p) 27rad = np.arccos(np.clip(inner/norms, -1.0, 1.0)) 28 29# rotate 30rotation = R.from_rotvec(rad * axis) 31rotated_particles = rotation.apply(particles) 32 33print(rotated_particles)

投稿2022/07/24 11:37

melian

総合スコア19703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lily_1007

2022/07/25 04:06

ありがとうございます。あとから回転行列の計算コードも作成してみて、melian様のコードの結果と合うことも確認できました。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問