三维空间上的旋转

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_20280061/article/details/52025762

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>

    typedef struct point{  //二维平面的点
        double x;
        double y;
    }Point;

    typedef struct point_3D{ //三维空间上的点
     double x;
     double y;
     double z;
    }point_3D;

    double ret[3][3] ={0}; //存储矩阵的乘积

    /** \brief
     *  二维平面的转换
     * \param
     * \param
     * \return
     *
     */
    Point* Rot_2D(double x1, double y1, float ceta)
    {
        Point *p2 = (Point *)malloc(sizeof(Point));
        p2->x = cos(ceta)*x1 - sin(ceta)*y1;
        p2->y = cos(ceta)*y1 + sin(ceta)*x1;
        return p2;
    }

    /** \brief 矩阵乘法
     *
     * \param
     * \param
     * \return
     *
     */

    void matrix_multipy(double martix1[3][3], double martix2[3][3])
    {
     int i,j,k,l;
     for(i=0;i<3;i++) //前行数
     {
         for(j=0;j<3;j++) //后列数
         {
             ret[i][j]=0; //初始化为0,每次计算结果存储
             for(k=0;k<3;k++)
             {
                 ret[i][j] += (martix1[i][k] * martix2[k][j]);
             }
         }
     }
    }
    /** \brief 打印矩阵
     *
     * \param
     * \param
     * \return
     *
     */

    void output_martix(double martix[3][3])
    {
        int i,j;
        for(i=0;i<3;i++)
        {
            for(j=0;j<3;j++)
                printf("%.2lf\t",martix[i][j]);
            printf("\n");
        }
         printf("\n");
    }
    /** \brief 三维空间上的旋转变换
     *
     * \param
     * \param
     * \return
     *
     */

    point_3D *Rot_3D(double ceta1, double ceta2, double ceta3,double x1,double y1,double z1)
    {
        double rotZ[3][3] = {{cos(ceta3),-sin(ceta3),0},{sin(ceta3),cos(ceta3),0},{0,0,1}};
        double rotY[3][3] = {cos(ceta2),0,sin(ceta2),0,1,0,-sin(ceta2),0,cos(ceta2)};
        double rotX[3][3] = {1,0,0,0,cos(ceta1),-sin(ceta1),0,sin(ceta1),cos(ceta1)};
        /*
        output_martix(rotZ);
        output_martix(rotY);
        output_martix(rotX);
        */
        point_3D *rot_3D = (point_3D *)malloc(sizeof(point_3D));
        matrix_multipy(rotZ,rotY);
        double temp[3][3];
        memcpy(temp,ret,3*3*8); //保存中间值
        matrix_multipy(temp,rotX); //得到rot_3D
        rot_3D->x = ret[0][0]*x1 + ret[0][1]*y1 + ret[0][2]*z1;
        rot_3D->y = ret[1][0]*x1 + ret[1][1]*y1 + ret[1][2]*z1;
        rot_3D->z = ret[2][0]*x1 + ret[2][1]*y1 + ret[2][2]*z1;
        return rot_3D;
    }

    /** \brief 三维空间上直接套用公式
     *
     * \param
     * \param
     * \return
     *
     */

    point_3D *re(double ceta1, double ceta2, double ceta3,double x1, double y1, double z1)
    {
         point_3D *p3 = (point_3D *)malloc(sizeof(point_3D));
         p3->x = x1 * cos(ceta1)*cos(ceta2) + y1*(cos(ceta1)*sin(ceta2)*sin(ceta3)-sin(ceta1)*cos(ceta3)) + z1 *(sin(ceta1)*sin(ceta3)+cos(ceta1)*sin(ceta2)*cos(ceta3));
         p3->y = x1 * sin(ceta1)*cos(ceta2) + y1 *(cos(ceta1)*cos(ceta3)+ sin(ceta1)*sin(ceta2)*sin(ceta3)) + z1 *(sin(ceta1)*sin(ceta2)*cos(ceta3)-cos(ceta1)*sin(ceta3));
         p3->z = x1 * (-sin(ceta2)) + y1 *(cos(ceta2)*sin(ceta3)) +z1*(cos(ceta2)*cos(ceta3));
         return p3;
    }

    int main()
    {
        int sel;
        while(1){
            printf("select to ROT_2D(0) or ROT_3D(1) \n");
            scanf("%d",&sel);
            if(sel==0){
                printf("input p1->x p1->y the incuded angle between p1 and p2 ceta\n");
                double x1,y1;
                float ceta;
                scanf("%lf %lf %f",&x1, &y1, &ceta);
                Point *p2 = (Point *)malloc(sizeof(Point));
                p2 = Rot_2D(x1, y1, (float)M_PI/180*ceta);
                printf("P2->x = %lf, P2->y = %lf \n\n",p2->x,p2->y);
            }
           if(sel==1){
                printf("input p1->x1, p1->y1, p1->z1 and ceta1, ceta2, ceta3 \n");
                double x2,y2,z2;
                double ceta1,ceta2,ceta3;
                scanf("%lf %lf %lf %lf %lf %lf",&x2, &y2, &z2, &ceta1, &ceta2, &ceta3);
                point_3D *p3 = (point_3D *)malloc(sizeof(point_3D));
                p3 = Rot_3D(ceta1*M_PI/180,ceta2*M_PI/180,ceta3*M_PI/180,x2,y2,z2);
                //p3 = Rot_3D(M_PI/2, M_PI/2, -M_PI/2, 5, 5, 5);  //用例
                //p3 = re(M_PI/2,M_PI/2,-M_PI/2,5,5,5);   //直接套用公式
                printf("p2->x = %lf  p2->y = %lf  p2->z = %lf\n\n",p3->x,p3->y,p3->z);
            }
        }
        return 0;
    }

猜你喜欢

转载自blog.csdn.net/sinat_20280061/article/details/52025762