[3次元の回転 回転後の位置座標算出]のためのクラス, Python(パイソン) 使って作ってみた ,ソースプログラムリスト あり

Python(パイソン) プログラム作ってみた インデックス へ
-----

2024.8.23 presented in [note] ( //note.com/runningWater/ )
2024.8.24 rewritten

----------
1 はじめに

これ以降に記述されている内容は、このようなコンピューター・プログラムを制作した、というような事を、ただ、述べているに過ぎない。

以下の記述を読んだ人が、それを単に参考にする、というのであれば、問題は無いと、思われる。

しかし、記述されている内容に沿って、その人が、そこに記されているのと同様の制作や作業を行った際に、その制作、作業、コンピューターの作動の結果、使用されたコンピューター等、様々な方面において、何らかの問題が発生しない、という保証は、全くない。

その制作、作業、コンピューターの作動の結果、その人や、その人が所属している組織、その人が使用した様々な機器、インフラストラクチャー等の、身の上にどのような事が起ころうとも、私は一切、責任を負わない。

このプログラムは、Python(パイソン) 言語を使って、記述されている。

----------
2 どんなものを作ったのか

3次元の画像処理を行う際には、ある座標軸を中心にして回転を行った後の、位置座標を求めたい、というような事が、しばしばある。そのような時には、[回転角度を指定し、それに対応する行列を作成し、その行列を使って、計算を]、というような手順を踏む事になるだろう。

時には、2度の回転を連続して行った後の、位置座標を求めたい、というような事も、あるだろう。

(例えば、[Z軸を中心として、30度回転し、その直後に、Y軸を中心として、45度回転し]、というように)

そのような時には、[2度目の回転に対応する行列] と [1度目の回転に対応する行列] との積を求めておけば、それを、[連続的回転に対応するような行列] として使うことができるのだろう、と考えた。

そのような考えのもとに、できたのが、以下に述べるものである。

----------
3 プログラムの内容

下記のような、1個のモジュールを、作ってみた。

コンストラクターの引数に対しては、

 arg_first_rotation_around_axis に、1度目の回転の中心となる軸の種別(X , Y , Z)を与え、
 arg_first_rotation_angle_degree に、回転角度を与える
 
と、いうようにした。

1度目の回転だけでよし、ということであれば、 
 arg_need_Y_N_second_rotation には、"N" を与え
 
1度目の回転、2度目の回転を、連続して、ということであれば、
 arg_need_Y_N_second_rotation には、"Y" を与え
 arg_second_rotation_around_axis
 arg_second_rotation_angle_degree
 に、2度目の回転に関する情報を与える、というようにした。
 
行列の積は、[numpy] の [matmul] を使って、求めるようにした。

そのようにしてコンストラクトされた、このクラスに属するインスタンスに対して、
 arg_list_cordinate_before_rotation に、回転前の座標値( [x , y , z] ) を与え、
 calculate_cordinate_after_rotation メソッドをコールすると、回転後の座標値が、返ってくる、というようにした。
 

===============
ファイル名 [MatrixFor3DRotaion.py]

----------


import numpy as NUMPY
import math

#===========================================
class MatrixFor3DRotaion :

    CV_CLASS_NAME = "MatrixFor3DRotaion"

    #------------------------------------------------------------
        # definition of constructer
    def __init__( self
                , arg_requester_module
                , arg_requester_function
                      #when doing first rotation, around, what axis?
                , arg_first_rotation_around_axis
                      #when doing first rotation, how dgree, used?
                , arg_first_rotation_angle_degree

                , arg_need_Y_N_second_rotation

                      #when doing second rotation, around, what axis?
                , arg_second_rotation_around_axis
                      #when doing second rotation, how dgree, used?
                , arg_second_rotation_angle_degree
                ) :

        methode_name = "constructer"

        print ( "==================================" )
        print ( "Enter into , Class = " + MatrixFor3DRotaion.CV_CLASS_NAME
                      + " , methode = " + methode_name )
        print ( "    arg_requester_module = " + arg_requester_module
                   + " , arg_requester_function = " + arg_requester_function )
        print ( "==================================" )

        self.iv_first_rotation_around_axis = arg_first_rotation_around_axis
        self.iv_first_rotation_angle_degree = \
                 arg_first_rotation_angle_degree
        self.iv_first_rotation_angle_radian  \
            = self.iv_first_rotation_angle_degree  \
                * ( math.pi / 180.0 )
        self.iv_ins_MatrixUsingNUMPY_for_first_rotation \
            = self.make_matrix ( \
                  self.iv_first_rotation_around_axis
                , self.iv_first_rotation_angle_radian
                           )
        self.iv_need_Y_N_second_rotation = arg_need_Y_N_second_rotation

        if ( self.iv_need_Y_N_second_rotation != "Y" ) :
            self.iv_ins_MatrixUsingNUMPY_for_rotation \
               = self.iv_ins_MatrixUsingNUMPY_for_first_rotation

            self.iv_second_rotation_around_axis = " "
            self.iv_second_rotation_angle_degree = 0
            self.iv_second_rotation_angle_radian = 0

            print ( "self.iv_need_Y_N_second_rotation = " /
                           + self.iv_need_Y_N_second_rotation )

            print ( "self.iv_ins_MatrixUsingNUMPY_for_first_rotation = " )
            print ( self.iv_ins_MatrixUsingNUMPY_for_first_rotation )
            print ( "self.iv_ins_MatrixUsingNUMPY_for_rotation = " )
            print (  self.iv_ins_MatrixUsingNUMPY_for_rotation )

            print ( "==================================" )
            print ( "Exit from , Class = " +  MatrixFor3DRotaion.CV_CLASS_NAME
                      + " , methode = " + methode_name )
            print ( "    arg_requester_module = " + arg_requester_module
                   + " , arg_requester_function = " + arg_requester_function )
            print ( "==================================" )

            return

        else :   # need_Y_N_second_rotation
            self.iv_second_rotation_around_axis = \
                     arg_second_rotation_around_axis
            self.iv_second_rotation_angle_degree = \
                     arg_second_rotation_angle_degree
            self.iv_second_rotation_angle_radian  \
                = self.iv_second_rotation_angle_degree  \
                          * ( math.pi / 180.0 )

            self.iv_ins_MatrixUsingNUMPY_for_second_rotation \
                   = self.make_matrix ( \
                          self.iv_second_rotation_around_axis
                        , self.iv_second_rotation_angle_radian
                               )
                     # make matrix of multiplaying first and second rotation
            self.iv_ins_MatrixUsingNUMPY_for_rotation \
                = NUMPY.matmul (  \
                       self.iv_ins_MatrixUsingNUMPY_for_second_rotation
                     , self.iv_ins_MatrixUsingNUMPY_for_first_rotation
                               )

            print ( "self.iv_need_Y_N_second_rotation = " \
                           + self.iv_need_Y_N_second_rotation )

            print ( "self.iv_ins_MatrixUsingNUMPY_for_second_rotation = " )
            print ( self.iv_ins_MatrixUsingNUMPY_for_second_rotation )
            print ( "self.iv_ins_MatrixUsingNUMPY_for_first_rotation = " )
            print ( self.iv_ins_MatrixUsingNUMPY_for_first_rotation )
            print ( "self.iv_ins_MatrixUsingNUMPY_for_rotation = " )
            print (  self.iv_ins_MatrixUsingNUMPY_for_rotation )

            print ( "==================================" )
            print ( "Exit from , Class = " +  MatrixFor3DRotaion.CV_CLASS_NAME
                      + " , methode = " + methode_name )
            print ( "    arg_requester_module = " + arg_requester_module
                   + " , arg_requester_function = " + arg_requester_function )
            print ( "==================================" )

            return

               # ---------------------------------------
        print ( "==================================" )
        print ( "Exit from , Class = " +  MatrixFor3DRotaion.CV_CLASS_NAME
                      + " , methode = " + methode_name )
        print ( "    arg_requester_module = " + arg_requester_module
                   + " , arg_requester_function = " + arg_requester_function )
        print ( "==================================" )

    #------------------------------------------------------------
    def  calculate_cordinate_after_rotation ( self   \
               , arg_list_cordinate_before_rotation
                                            ) :

        methode_name = "calculate_cordinate_after_rotation"

        # print ( "==================================" )
        # print ( "Enter into  , Class = " +  MatrixFor3DRotaion.CV_CLASS_NAME
        #               + " , methode = " + methode_name )
        # print ( "    arg_list_cordinate_before_rotation = " )
        # print ( arg_list_cordinate_before_rotation )
        # print ( "==================================" )

        cordinate_before_NUMPY =   \
              NUMPY.array (        \
                  [ \
                    [ arg_list_cordinate_before_rotation [ 0 ] ] \
                  , [ arg_list_cordinate_before_rotation [ 1 ] ] \
                  , [ arg_list_cordinate_before_rotation [ 2 ] ] \
                  ] \
                          )

        # print ( "cordinate_before_NUMPY = " )
        # print ( cordinate_before_NUMPY )

        # print ( "self.iv_ins_MatrixUsingNUMPY_for_rotation = " )
        # print ( self.iv_ins_MatrixUsingNUMPY_for_rotation )

        # print ( "*****************************" )
        # print ( "*****************************" )
        # print ( "*****************************" )

        return_matrixUsingNUMPY = NUMPY.matmul (   \
                 self.iv_ins_MatrixUsingNUMPY_for_rotation
                ,cordinate_before_NUMPY
                 )

        # print ( "cordinate_before_NUMPY = " )
        # print ( cordinate_before_NUMPY )

        # print ( "self.iv_ins_MatrixUsingNUMPY_for_rotation = " )
        # print ( self.iv_ins_MatrixUsingNUMPY_for_rotation )

        # print ( "return_matrixUsingNUMPY = " )
        # print ( return_matrixUsingNUMPY )

        # print ( "************************" )
        # print ( "matmul done" )
        # print ( "************************" )

        return  return_matrixUsingNUMPY

    #------------------------------------------------------------
    def  make_matrix ( self   \
                    , arg_rotation_around_axis
                    , arg_rotation_angle_radian
                                            ) :

        methode_name = "make_matrix"

        rotation_matrix_value = [
                                  [ 1 , 0 , 0 ] ,
                                  [ 0 , 1 , 0 ] ,
                                  [ 0 , 0 , 1 ]
                                ]

        if ( arg_rotation_around_axis == "Z" ) :
                              #rotation around Z axis
                              # direction X axis --> Y axis

                      #--------- row 1 ---------------
            rotation_matrix_value [ 1 - 1 ] [ 1 - 1 ]    \
                      = math.cos ( arg_rotation_angle_radian )
            rotation_matrix_value [ 1 - 1  ] [ 2 - 1 ]  \
                      = ( 0.0 - math.sin ( arg_rotation_angle_radian ) )
            rotation_matrix_value [ 1 - 1 ]  [ 3 - 1 ]  \
                      = 0.0
                      #---------- row 2 --------------
            rotation_matrix_value [ 2 - 1 ]  [ 1 - 1 ]   \
                         = math.sin ( arg_rotation_angle_radian )
            rotation_matrix_value [ 2 - 1 ]  [ 2 - 1 ]    \
                         = math.cos ( arg_rotation_angle_radian )
            rotation_matrix_value [ 2 - 1 ]  [ 3 - 1 ]     \
                         = 0.0
                     #---------- row 3 --------------
            rotation_matrix_value [ 3 - 1 ]  [ 1 - 1 ]    \
                         = 0.0
            rotation_matrix_value [ 3 - 1 ]  [ 2 - 1 ]  \
                         = 0.0
            rotation_matrix_value [ 3 - 1 ]  [ 3 - 1 ]   \
                         = 1.0

            return_matrixUsingNUMPY   \
                = NUMPY.array ( rotation_matrix_value )
            return  return_matrixUsingNUMPY

        #---------------------------------------------------
        if ( arg_rotation_around_axis == "Y" ) :
                              #rotation around Y axis
                              # direction X axis --> Z axis

                      #--------- row 1 ---------------
            rotation_matrix_value [ 1 - 1 ]   [ 1 - 1 ]    \
                         = math.cos ( arg_rotation_angle_radian )
            rotation_matrix_value [ 1 - 1  ]    [ 2 - 1 ]     \
                         = 0.0
            rotation_matrix_value [ 1 - 1 ]  [ 3 - 1 ]      \
                         = math.sin ( arg_rotation_angle_radian )
                      #---------- row 2 --------------
            rotation_matrix_value [ 2 - 1 ]   [ 1 - 1 ]    \
                         = 0.0
            rotation_matrix_value [ 2 - 1 ]   [ 2 - 1 ]    \
                         = 1.0
            rotation_matrix_value [ 2 - 1 ]   [ 3 - 1 ]      \
                         = 0.0
                     #---------- row 3 --------------
            rotation_matrix_value [ 3 - 1 ]   [ 1 - 1 ]   \
                         = 0.0 - math.sin ( arg_rotation_angle_radian )
            rotation_matrix_value [ 3 - 1 ]   [ 2 - 1 ]    \
                         = 0.0
            rotation_matrix_value [ 3 - 1 ]   [ 3 - 1 ]    \
                         = math.cos ( arg_rotation_angle_radian )

            return_matrixUsingNUMPY   \
                = NUMPY.array ( rotation_matrix_value )
            return  return_matrixUsingNUMPY

        #---------------------------------------------------
        if ( arg_rotation_around_axis == "X" ) :
                              #rotation around X axis
                              # direction Y axis --> Z axis

                      #--------- row 1 ---------------
            rotation_matrix_value [ 1 - 1 ]   [ 1 - 1 ]     \
                         = 1.0
            rotation_matrix_value [ 1 - 1  ]   [ 2 - 1 ]     \
                         = 0.0
            rotation_matrix_value [ 1 - 1 ]   [ 3 - 1 ]     \
                         = 0.0
                      #---------- row 2 --------------
            rotation_matrix_value [ 2 - 1 ]  [ 1 - 1 ]     \
                         = 0.0
            rotation_matrix_value [ 2 - 1 ]   [ 2 - 1 ]     \
                         = math.cos ( arg_rotation_angle_radian )
            rotation_matrix_value [ 2 - 1 ]   [ 3 - 1 ]     \
                         = 0.0 - math.sin ( arg_rotation_angle_radian )
                     #---------- row 3 --------------
            rotation_matrix_value [ 3 - 1 ]   [ 1 - 1 ]    \
                         = 0.0
            rotation_matrix_value [ 3 - 1 ]   [ 2 - 1 ]     \
                         = math.sin ( arg_rotation_angle_radian )
            rotation_matrix_value [ 3 - 1 ]    [ 3 - 1 ]     \
                         = math.cos ( arg_rotation_angle_radian )

            return_matrixUsingNUMPY   \
                = NUMPY.array ( rotation_matrix_value )
            return  return_matrixUsingNUMPY

        #-----------------------------------------
        return_matrixUsingNUMPY   \
                = NUMPY.array ( rotation_matrix_value )
        return  return_matrixUsingNUMPY

   #-----------------------------------------
   # Test Run

# requester_module = "___"
# requester_function = "Test Run"

# methode_name = "Test Run"

# print ( "==================================" )
# print ( "==== Test Run  ==============================" )
# print ( "==================================" )
# print ( " " )

# print ( "==================================" )
# print ( "Enter into , Class = " + MatrixFor3DRotaion.CV_CLASS_NAME
#                      + " , methode = " + methode_name )
# print ( "==================================" )

# print ( "NUMPY.__version__ = " , NUMPY.__version__ )

# matrix_1 = MatrixFor3DRotaion (  \
#                  "___"  # arg_requester_module
#                , "---"  # arg_requester_function
#
                      #when doing first rotation, around, what axis?
#                , "Z"    # arg_first_rotation_around_axis
#                      #when doing first rotation, how dgree, used?
#                , 30    # arg_first_rotation_angle_degree

#                , "Y"   # arg_need_Y_N_second_rotation

                      #when doing second rotation, around, what axis?
#                , "X"    #  arg_second_rotation_around_axis
#                      #when doing second rotation, how dgree, used?
#                , 45      #  arg_second_rotation_angle_degree
#                )

# return_1 = matrix_1.calculate_cordinate_after_rotation (    \
#                   [ 1.0  ,  0  ,  0 ] )
# print ( "return_1 = " )
# print ( return_1 )

-----

Python(パイソン) プログラム作ってみた インデックス へ


この記事が気に入ったらサポートをしてみませんか?