四元数 c语言 坐标转换,eigen 四元数进行坐标旋转

(《视觉SLAM十四讲》第三讲习题7)设有小萝卜一号和二号在世界坐标系中。一号位姿q1 = [0.35, 0.2, 0.3, 0.1],t1=[0.3, 0.1, 0.1]。二号位姿q2=[-0.5, 0.4, -0.1, 0.2], t2=[-0.1, 0.5, 0.3].某点在一号坐标系下坐标为p=[0.5, 0, 0.2].求p在二号坐标系下的坐标

假设在世界坐标系中p点的坐标为P。

用四元数做旋转则有(在Eigen中四元数旋转为q×v,数学中则为q×v×q^-1):

q1 × P + t1 = p1

q2 × P + t2 = p2

由上两式分别解算出:

P = q1^-1 × (p1 - t1)

P = q2^-1 × (p2 - t2)

两式联立求解则得到:

p2 = q2 × q1^-1 × (p1 - t1) + t2

如果用欧拉矩阵(设一号欧拉矩阵为T1,二号欧拉矩阵为T2)则有:

p1 = T1 × P

p2 = T2 × P

求解P:

P = T1^-1 × p1

P = T2^-1 × p2

联立求解则有:

p2 = T2 × T1^-1 × p1

以下则是用Eigen实现的代码:

#include

using namespace std;

#include

#include

int main()

{

//四元数

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
public void Polygon_Trans4(IFeatureClass pFeatureCls, string strPath, string strFilename, ProgressBar pBar) { if (pFeatureCls == null || strPath == "" || strFilename == "") return; createNewShape(strPath, strFilename, pFeatureCls); IFeatureCursor pFeatCursor = pFeatureCls.Search(null, false); IFeature pFeature = pFeatCursor.NextFeature(); //打开目标图层 IWorkspaceFactory pWSF = new ShapefileWorkspaceFactoryClass(); IWorkspace pWS = pWSF.OpenFromFile(strPath, 0); IFeatureWorkspace pFWS = (IFeatureWorkspace)pWS; IFeatureClass pTargetFClass = pFWS.OpenFeatureClass(strFilename); IWorkspaceEdit pWSEdit = pWS as IWorkspaceEdit; pWSEdit.StartEditOperation(); pWSEdit.StartEditing(false); ITable pTble = (ITable)pFeatureCls; int lCunt = pTble.RowCount(null); pBar.Visible = true; pBar.Minimum = 0; pBar.Maximum = lCunt; pBar.Step = 1; IFeature pNewFeature; IPolygon pOutPolygon; IGeometryCollection pOutGeos; IPolygon pInPolygon; IGeometryCollection pInGeos; IPoint pOutPnt = new PointClass(); IPointCollection pOutPnts; while (pFeature != null) { pBar.PerformStep(); pNewFeature = pTargetFClass.CreateFeature(); pOutPolygon = new PolygonClass(); pOutGeos = pOutPolygon as IGeometryCollection; //获取原图形 pInPolygon = pFeature.Shape as IPolygon; pInGeos = pInPolygon as IGeometryCollection; for (int m = 0; m < pInGeos.GeometryCount; m++) { IGeometry pInGeo = pInGeos.get_Geometry(m); IPointCollection pInPnts = pInGeo as IPointCollection; pOutPnts = new PolygonClass(); object missing = Type.Missing; for (int n = 0; n < pInPnts.PointCount; n++) { IPoint pInPnt = pInPnts.get_Point(n); //转换点坐标 pOutPnt.X = ClsParas4.m_OffY + pInPnt.Y * ClsParas4.m_vb + pInPnt.X * ClsParas4.m_va; pOutPnt.Y = ClsParas4.m_OffX + pInPnt.Y * ClsParas4.m_va - pInPnt.X * ClsParas4.m_vb; pOutPnts.AddPoint(pOutPnt, ref missing, ref missing); } ISegmentCollection pSegmentCols = new RingClass(); pSegmentCols.AddSegmentCollection(pOutPnts as ISegmentCollection); pOutGeos.AddGeometry(pSegmentCols as IGeometry, ref missing, ref missing); } for (int i = 0; i < pFeature.Fields.FieldCount; i++) { if (pNewFeature.Fields.get_Field(i).Name.ToString().Equals("FID", StringComparison.CurrentCultureIgnoreCase) || pNewFeature.Fields.get_Field(i).Name.ToString().Equals("SHAPE", StringComparison.CurrentCultureIgnoreCase)) continue; pNewFeature.set_Value(i, pFeature.get_Value(i)); } pNewFeature.Shape = pOutPolygon as IGeometry; pNewFeature.Store(); pFeature = pFeatCursor.NextFeature(); } pBar.Visible = false; pWSEdit.StopEditOperation(); pWSEdit.StopEditing(true); }
要将三维坐标矩阵转换为四元数,需要进行以下步骤: 1. 将三维坐标矩阵转换为旋转矩阵 2. 将旋转矩阵转换为四元数 以下是基于C语言的代码实现: ```c #include <stdio.h> #include <math.h> typedef struct { float x, y, z; } Vector3; typedef struct { float w, x, y, z; } Quaternion; void matrixToQuaternion(float m[3][3], Quaternion* q) { float trace = m[0][0] + m[1][1] + m[2][2]; float S; if (trace > 0.0f) { S = sqrtf(trace + 1.0f) * 2.0f; q->w = 0.25f * S; q->x = (m[2][1] - m[1][2]) / S; q->y = (m[0][2] - m[2][0]) / S; q->z = (m[1][0] - m[0][1]) / S; } else if ((m[0][0] > m[1][1]) && (m[0][0] > m[2][2])) { S = sqrtf(1.0f + m[0][0] - m[1][1] - m[2][2]) * 2.0f; q->w = (m[2][1] - m[1][2]) / S; q->x = 0.25f * S; q->y = (m[0][1] + m[1][0]) / S; q->z = (m[0][2] + m[2][0]) / S; } else if (m[1][1] > m[2][2]) { S = sqrtf(1.0f + m[1][1] - m[0][0] - m[2][2]) * 2.0f; q->w = (m[0][2] - m[2][0]) / S; q->x = (m[0][1] + m[1][0]) / S; q->y = 0.25f * S; q->z = (m[1][2] + m[2][1]) / S; } else { S = sqrtf(1.0f + m[2][2] - m[0][0] - m[1][1]) * 2.0f; q->w = (m[1][0] - m[0][1]) / S; q->x = (m[0][2] + m[2][0]) / S; q->y = (m[1][2] + m[2][1]) / S; q->z = 0.25f * S; } } int main(void) { float matrix[3][3] = { {0.707f, 0.0f, 0.707f}, {0.0f, 1.0f, 0.0f}, {-0.707f, 0.0f, 0.707f} }; Quaternion quat; matrixToQuaternion(matrix, &quat); printf("Quaternion: (%f, %f, %f, %f)\n", quat.w, quat.x, quat.y, quat.z); return 0; } ``` 在此示例中,旋转矩阵被定义为一个3x3的数组。然后,调用`matrixToQuaternion`函数将旋转矩阵转换为四元数,并将结果存储在`quat`变量中。最后,四元数的值被打印出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值