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

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

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

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

Q&A

0回答

3632閲覧

pythonでオイラー角をクォータニオンに変換し、ベジェ曲線補完をしたい

taiki9121

総合スコア18

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

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

0グッド

1クリップ

投稿2019/02/04 15:19

編集2019/02/04 15:31

pythonでオイラー角をクォータニオンで実装し、ベジェ曲線補完をしたいのですがいまいち実装方法がわかりません...

import numpy as np firstFlame=0 afterFlame=5 firstEuler=np.array([20,0,0]) #0フレーム目における姿勢のアングル(オイラー角) afterEuler=np.array([-19,30,0]) #5フレーム目における姿勢のアングル(オイラー角) BezierPoint=np.array([[0,0],[20,20],[107,107],[127,127]]) #ベジェ曲線における直線補間 BezierPoint2=np.array([[0,0],[0,127],[127,0],[127,127]]) #ベジェ曲線における曲線補間 time = np.arange(0,1,0.01) #0~5の間をクォータニオンでベジェ曲線補完し、最終的にオイラー角に変換したい。 #実行結果を以下のようにしたい。 #ベジェ曲線における直線補間の場合(BezierPoint) #[0.2 0.4 0.6 0.8 1.0]#ベジェ曲線の補間係数の値 #****************************************** #[20, 0, 0]0フレーム目 #[12.3, 6.2, 1.7] 1フレーム目 #[4.4, 12.1, 2.5] 2フレーム目 #[-3.4, 17.9, 2.5] 3フレーム目 #[-11.3, 23.8, 1.7] 4フレーム目 #ベジェ曲線における曲線補間の場合(BezierPoint2) #[0.0, 0.01747555, 0.11148985, 0.88851015, 0.98252445]ベジェ曲線の補間係数の値 #****************************************** #[20, 0, 0]0フレーム目 #[19.3, 0.6, 0.2] 1フレーム目 #[15.7, 3.5, 1.1] 2フレーム目 #[-14.7, 26.5, 1.1] 3フレーム目 #[-18.3, 29.4, 0.2] 4フレーム目 #現在の実装コードではオイラー角をそのままベジェ曲線補間しているため、以下のような出力結果となってしまう。 #ベジェ曲線における直線補間の場合(BezierPoint) #[0.0, 0.01747555, 0.11148985, 0.88851015, 0.98252445]ベジェ曲線の補間係数の値 #****************************************** #[[ 20. 0. 0. ] 0フレーム目 # [ 12.2 6. 0. ] 1フレーム目 # [ 4.4 12. 0. ] 2フレーム目 # [ -3.4 18. 0. ] 3フレーム目 # [-11.2 24. 0. ]] 4フレーム目 #ベジェ曲線における曲線補間の場合(BezierPoint2) #[0.0, 0.01747555, 0.11148985, 0.88851015, 0.98252445]ベジェ曲線の補間係数の値 #****************************************** #[[ 20. 0. 0. ] 0フレーム目 #[ 19.31845359 0.52426647 0. ] 1フレーム目 #[ 15.65189583 3.34469552 0. ] 2フレーム目 #[-14.65189583 26.65530448 0. ] 3フレーム目 #[-18.31845359 29.47573353 0. ]]4フレーム目 実装コードの全体像 #******************************************************************** import numpy as np import bisect import matplotlib.pyplot as plt def bezier(N,cuttime,P,X): time = np.arange(0,1,cuttime)#ベジエ曲線におけるt firstEuler= np.array([20,0,0])#0フレーム目における姿勢のアングル(オイラー角) afterEuler = np.array([-19,30,0])#5フレーム目における姿勢のアングル(オイラー角) num = np.arange(N + 1) Y = np.outer(P,(np.array(time ** np.c_[num[::-1]]).T * np.array((1 - time) ** np.c_[num]).T * np.array([1,N,N,1])).T[::-1]).T#ベジエ曲線を計算 D = np.reshape(Y,(len(time) * (N + 1),len(P),(N + 1),(N + 1),2))#ベジエ曲線を計算 point = np.array([[sum([D.transpose(3,2,1,0,4)[i][j][k][len(time) * i:len(time) * i + len(time)] for i in range(N + 1)])for j in range(N + 1)]for k in range(len(P))])#求まったベジエ曲線の座標点を整理 bezierCoeff = point.T#ベジェ曲線の(time=0,0.1,0.2...1.1)における(X,Y)座標(bezierCoeff[1]はY軸成分、bezierCoeff[0]はX軸成分) plt.scatter(bezierCoeff[0].T[0][0],bezierCoeff[1].T[0][0])#0フレーム目の[0,0,127,0,0,127,127,127]におけるベジエ曲線 plt.show() coef = np.array((bezierCoeff[1][1:] - bezierCoeff[1][:-1]) / (bezierCoeff[0][1:] - bezierCoeff[0][:-1]))#ベジエ曲線の時間timeにおける変化量を計算 intercept = np.array((bezierCoeff[1][:-1] - coef * bezierCoeff[0][:-1]))#直線の切片を計算 res = np.apply_along_axis(lambda b: [np.digitize(X[i], b)for i in range(len(X))], 2, bezierCoeff[0].T) - 1 res = np.array([res.transpose(0,2,1)[i][i]for i in range(res.shape[0] - 1)]) res = np.array([[res[i][j][:-1]for j in range(res.shape[1])]for i in range(res.shape[0])])#切片と変化量のインデックス absEuler = afterEuler - firstEuler #姿勢のアングルの差 bezierCoef=(X[0][:-1] * coef.T[0][0][res[0][0]] + intercept.T[0][0][res[0][0]]) / 127#0フレーム目の[0,0,127,0,0,127,127,127]におけるベジエ曲線の係数 print(np.outer(bezierCoef,absEuler) + firstEuler)#オイラー角をそのままベジェ曲線補間しているのでz軸が反映されない...四元数を用いて上記のような結果にしたい。 #return Z def main(): frame = np.array([0,5,8,13,15,17,18,24,28,30,0,15,30])#フレーム frame_abs = frame[1:] - frame[:-1] #(各フレームで対応付けられた4つのベジエ曲線の方向点を示す8つのパラメータ) point = np.array([[[0,0,127,0,0,127,127,127],[0,0,30,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127]],#0フレーム目 [[0,0,0,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,127,20,107,107,127,127],[0,0,20,20,107,107,127,127]],#5フレーム目 [[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,0,40,17,127,127,127],[0,0,20,20,107,107,127,127]],#8フレーム目 [[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127]],#13フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127]],#15フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127]],#17フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,0,120,107,107,127,127]],#18フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,107,107,127,127],[0,0,0,120,107,107,127,127]],#24フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,127,107,127,127],[0,0,0,120,127,107,127,127]],#28フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,127,107,127,127],[0,0,0,120,127,107,127,127]],#30フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,127,107,127,127],[0,0,0,120,127,107,127,127]],#0フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,127,107,127,127],[0,0,0,120,127,107,127,127]],#15フレーム目 [[0,0,0,127,0,127,127,127],[0,0,20,20,107,107,127,127],[0,0,20,20,127,107,127,127],[0,0,0,120,127,107,127,127]]])#30フレーム目 point = np.array(np.split(point, 4, axis=2)).transpose(1,2,0,3)#ベジエ曲線の8つのパラメータをshape=(4,2)に分割 X = 127 / frame_abs * np.array([np.arange(item + 1)for i,item in enumerate(frame_abs)]) Y = bezier(3,0.01,point,X) if __name__ == "__main__": main()

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

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

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

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

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

y_waiwai

2019/02/04 22:20

計算式、あるいは処理方法がわからないというはなしでしょうか それとも、計算式はわかってるけど実装法がわからないということでしょうか。
taiki9121

2019/02/04 23:33

ご回答ありがとうございます。 どちらかというと計算式と処理方法の方でしょうか。 どのような計算式で与えられるかを教えていただければあとは自力で実装したいです。 あれから色々調べまして、 pyquaternionのQuaternion.Slerpなんかも使ってみましだが、やはりz軸は反映されませんでした,,,(使い方が悪いだけかも)
stdio

2019/02/05 01:36

なにが分からないのですか? 文を読み限り、オイラー角 -> クォータニオン -> ベジェ曲線補完という流れになっていますが。このうちのどこが分からないのでしょうか?
taiki9121

2019/02/05 05:50

ご返信ありがとうございます。 分かりにくくて申し訳ございません。 オイラー角→クオータニオンの変換は数式がわからない感じです。 また、クオータニオン→ベジェ曲線補間は実装方法がわからないです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問