三维坐标转化

一,点转换:初系的点坐标转换为末系的点坐标

初始坐标系以StartOrigin为原点建立坐标系,末坐标系以FinalOrigin为原点建立坐标系,在初系中FinalOrigin点的坐标为Vector3 FinalOrigin_StartOrigin=new Vector3(x1,y1,z1);,将初系从StartOrigin点平移到FinalOrigin点,然后将初系绕Z轴旋转Yaw度,再绕Y轴旋转Pitch度,最后绕X轴旋转Roll度得到末系。

现在有一个点point在初系中的坐标为Vector3 point_StartOrigin =new Vector3(x2,y2,z2);请问在末系中point点的坐标为多少?

1.获取初系变为末系的转换矩阵:使用GetTransformationMatrix方法根据FinalOrigin_StartOrigin、Yaw、Pitch、Roll可以得到初系转为末系的转换矩阵,

2.用TransformPoint()方法利用转换矩阵转换点的坐标

        public static void Main()
        {
            Vector3 FinalOrigin_StartOrigin=new Vector3(x1,y1,z1);
            Vector3 point_StartOrigin =new Vector3(x2,y2,z2);
            StartToFinal=GetTransformationMatrix(FinalOrigin_StartOrigin,Yaw, Pitch, Roll);
            Vector3 point_FinalOrigin=TransformPoint(point_StartOrigin,StartToFinal);
            
        } 

        public static Matrix4x4 GetTransformationMatrix(Vector3 FinalOrigin, float yaw, float pitch, float roll)// FinalOrigin:初系当中,末系原点的坐标
        {
            // 定义旋转角度(弧度)
            yaw = (float)(yaw * Math.PI / 180); // 90度
            pitch = (float)(pitch * Math.PI / 180); // 0度
            roll = (float)(roll * Math.PI / 180); // 0度
            // 创建单位矩阵
            Matrix4x4 transformationMatrix = Matrix4x4.Identity;
            // 创建平移矩阵
            Vector3 translation = new Vector3(-FinalOrigin.X, -FinalOrigin.Y, -FinalOrigin.Z);
            Matrix4x4 translationMatrix = Matrix4x4.CreateTranslation(translation);
            // 添加平移部分
            transformationMatrix *= translationMatrix;
            // 将C1坐标系绕自身z轴顺时针旋转yaw度
            transformationMatrix *= Matrix4x4.CreateRotationZ((-yaw));
            // 将C1坐标系绕自身y轴顺时针旋转pitch度
            transformationMatrix *= Matrix4x4.CreateRotationY((-pitch));
            // 将C1坐标系绕自身x轴顺时针旋转roll度
            transformationMatrix *= Matrix4x4.CreateRotationX((-roll));
            return transformationMatrix;
        }

        public static Vector3 TransformPoint(Vector3 point, Matrix4x4 transformMatrix)//初坐标系中某点的坐标为point,初系经矩阵变换为末系,求末坐标系中该点的坐标
        {
            Vector4 homogeneousPoint = new Vector4(point, 1);
            Vector4 transformedPoint = Vector4.Transform(homogeneousPoint, transformMatrix);
            Vector3 result = new Vector3(transformedPoint.X, transformedPoint.Y, transformedPoint.Z);
            return result;
        }

注:

1.Vector3 point_FinalOrigin=TransformPoint(new Vector3(0,0,0),StartToFinal);可以求得末系中StartOrigin的坐标

2.使用以下代码求StartToFinal的逆矩阵可以求得末系转换成初系的转换矩阵FinalToStart

        public static void Main()
        {
            Matrix4x4 FinalToStart=GetInverseTransformationMatrix(StartToFinal);
        }
        public static Matrix4x4 GetInverseTransformationMatrix(Matrix4x4 transformationMatrix)//矩阵求逆
        {
            Matrix4x4 inverseTransformationMatrix;
            Matrix4x4.Invert(transformationMatrix, out inverseTransformationMatrix);

            return inverseTransformationMatrix;
        }

 

二,线转换:直线L与初系X轴夹角转换成与末系X轴夹角

初系中有一条直线L,L平行于初系的x-y平面,且与初系X轴的夹角为theta,请问L与末系X轴的夹角为多少?

1.用GetDirectionVector()获取直线L的方向向量Vector3 Final

2.将方向向量平移至初系的原点,此时方向向量的起点坐标为(0,0,0),终点坐标为Final

3.利用TransformPoint()方法和初系转末系的转换矩阵得到末系中方向向量起点、终点的坐标

4.两个坐标相减得到末系中直线L的方向向量

5.用GetAngleWithXAxis()求新的方向向量与末系X轴的夹角

        public static void Main()
        {
            float theta1 =TransformAngle(theta,StartToFinal);
        }
        public static float TransformAngle(float theta, Matrix4x4 transformMatrix)//
        {
            Vector3 Final = GetDirectionVector(theta);
            Vector3 Final_Chassis = TransformPoint(Final, transformMatrix);
            Vector3 Origin_Chassis = TransformPoint(new Vector3(0, 0, 0), transformMatrix);
            Vector3 Direction = Final_Chassis - Origin_Chassis;
            float theta1 = GetAngleWithXAxis(Direction);
            return theta1;
        }
        public static float GetAngleWithXAxis(Vector3 L)
        {
            // 计算方向向量在x轴上的投影长度
            float projectionOnXAxis = L.X;

            // 计算方向向量的模长
            float magnitudeOfL = (float)Math.Sqrt(L.X * L.X + L.Y * L.Y + L.Z * L.Z);

            // 计算夹角的余弦值
            float cosTheta = projectionOnXAxis / magnitudeOfL;

            // 计算夹角(以弧度为单位),然后转换为角度
            float thetaRadians = (float)Math.Acos(cosTheta);
            float thetaDegrees = thetaRadians * (180.0f / (float)Math.PI);
            if (L.Y < 0) thetaDegrees = -thetaDegrees;
            return thetaDegrees;
        }
        public static Vector3 GetDirectionVector(float theta)
        {
            // 将角度从度转换为弧度
            float thetaRadians = theta * (float)(Math.PI / 180.0);

            // 计算方向向量的各个分量
            float xComponent = (float)Math.Cos(thetaRadians);
            float yComponent = (float)Math.Sin(thetaRadians);
            float zComponent = 0.0f; // 因为直线平行于x-y平面,所以z分量为0
            Console.WriteLine($"Transformed Coordinate: ({xComponent}, {yComponent}, {zComponent})");
            return new Vector3(xComponent, yComponent, zComponent);
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值