设为首页收藏本站

中国膜结构网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

膜结构车棚
膜结构车棚膜结构资质国产膜材 膜结构网中国膜结构协会
查看: 189|回复: 1

ObjectARX中矩阵AcGeMatrix3d的使用介绍

[复制链接]
  • TA的每日心情
    开心
    2021-6-19 14:40
  • 签到天数: 1539 天

    [LV.Master]伴坛终老

    发表于 2020-12-29 15:45 | 显示全部楼层 |阅读模式
    1. 1、介绍
    2.   先介绍一下AcGeMatrix3d这个类,常见的点一般是Pt(X,Y,Z),相当于一个1×3矩阵,而矩阵相乘的话一般是第一个矩阵的列数要等于第二个矩阵的行数,所以我一开始天真的认为AcGeMatrix3d是个3×3矩阵,然而看过类介绍后没有发现矩阵相加减这种情况,纳闷平移是怎么用乘法实现的,原来用齐次坐标的概念如下:https://wenku.baidu.com/view/4b0324eae009581b6bd9eb40.html?from=search
    3. 在这里插入图片描述

    4. 在这里插入图片描述

    5. 2、使用例子
    6.   简单说一下三种比较常用的:平移、缩放、旋转;

    7. 2.1 平移
    8.   平移有两个set矩阵的方法setTranslation()和setToTranslation(),试过后发现没有区别;

    9. 为了方便debug调试,写了个结构体来转换出矩阵行列值查看:

    10. struct MatrixVector
    11. {
    12.         int nM11;
    13.         int nM12;
    14.         int nM13;
    15.         int nM14;

    16.         int nM21;
    17.         int nM22;
    18.         int nM23;
    19.         int nM24;

    20.         int nM31;
    21.         int nM32;
    22.         int nM33;
    23.         int nM34;

    24.         int nM41;
    25.         int nM42;
    26.         int nM43;
    27.         int nM44;

    28.         MatrixVector()
    29.         {
    30.                 nM11 = 1;
    31.                 nM12 = 0;
    32.                 nM13 = 0;
    33.                 nM14 = 0;

    34.                 nM21 = 0;
    35.                 nM22 = 1;
    36.                 nM23 = 0;
    37.                 nM24 = 0;

    38.                 nM31 = 0;
    39.                 nM32 = 0;
    40.                 nM33 = 1;
    41.                 nM34 = 0;

    42.                 nM41 = 0;
    43.                 nM42 = 0;
    44.                 nM43 = 0;
    45.                 nM44 = 1;
    46.         };
    47. };

    48. MatrixVector ConverMatrix(AcGeMatrix3d matxExp)
    49. {
    50.         MatrixVector stuMatrix;

    51.         stuMatrix.nM11 = matxExp.entry[0][0];
    52.         stuMatrix.nM12 = matxExp.entry[0][1];
    53.         stuMatrix.nM13 = matxExp.entry[0][2];
    54.         stuMatrix.nM14 = matxExp.entry[0][3];

    55.         stuMatrix.nM21 = matxExp.entry[1][0];
    56.         stuMatrix.nM22 = matxExp.entry[1][1];
    57.         stuMatrix.nM23 = matxExp.entry[1][2];
    58.         stuMatrix.nM24 = matxExp.entry[1][3];

    59.         stuMatrix.nM31 = matxExp.entry[2][0];
    60.         stuMatrix.nM32 = matxExp.entry[2][1];
    61.         stuMatrix.nM33 = matxExp.entry[2][2];
    62.         stuMatrix.nM34 = matxExp.entry[2][3];

    63.         stuMatrix.nM41 = matxExp.entry[3][0];
    64.         stuMatrix.nM42 = matxExp.entry[3][1];
    65.         stuMatrix.nM43 = matxExp.entry[3][2];
    66.         stuMatrix.nM44 = matxExp.entry[3][3];

    67.         return stuMatrix;
    68.     }
    69.    
    70.     AcGeMatrix3d ConverMatrixVector(MatrixVector stuMatrix)
    71.     {
    72.             AcGeMatrix3d matxExp;
    73.             matxExp.entry[0][0] = stuMatrix.nM11;
    74.             matxExp.entry[0][1] = stuMatrix.nM12;
    75.             matxExp.entry[0][2] = stuMatrix.nM13;
    76.             matxExp.entry[0][3] = stuMatrix.nM14;
    77.    
    78.             matxExp.entry[1][0] = stuMatrix.nM21;
    79.             matxExp.entry[1][1] = stuMatrix.nM22;
    80.             matxExp.entry[1][2] = stuMatrix.nM23;
    81.             matxExp.entry[1][3] = stuMatrix.nM24;
    82.                 matxExp.entry[2][0] = stuMatrix.nM31;
    83.                 matxExp.entry[2][1] = stuMatrix.nM32;
    84.                 matxExp.entry[2][2] = stuMatrix.nM33;
    85.                 matxExp.entry[2][3] = stuMatrix.nM34;

    86.                 matxExp.entry[3][0] = stuMatrix.nM41;
    87.                 matxExp.entry[3][1] = stuMatrix.nM42;
    88.                 matxExp.entry[3][2] = stuMatrix.nM43;
    89.                 matxExp.entry[3][3] = stuMatrix.nM44;

    90.                 return matxExp;
    91. }
    92. 1
    93. 2
    94. 3
    95. 4
    96. 5
    97. 6
    98. 7
    99. 8
    100. 9
    101. 10
    102. 11
    103. 12
    104. 13
    105. 14
    106. 15
    107. 16
    108. 17
    109. 18
    110. 19
    111. 20
    112. 21
    113. 22
    114. 23
    115. 24
    116. 25
    117. 26
    118. 27
    119. 28
    120. 29
    121. 30
    122. 31
    123. 32
    124. 33
    125. 34
    126. 35
    127. 36
    128. 37
    129. 38
    130. 39
    131. 40
    132. 41
    133. 42
    134. 43
    135. 44
    136. 45
    137. 46
    138. 47
    139. 48
    140. 49
    141. 50
    142. 51
    143. 52
    144. 53
    145. 54
    146. 55
    147. 56
    148. 57
    149. 58
    150. 59
    151. 60
    152. 61
    153. 62
    154. 63
    155. 64
    156. 65
    157. 66
    158. 67
    159. 68
    160. 69
    161. 70
    162. 71
    163. 72
    164. 73
    165. 74
    166. 75
    167. 76
    168. 77
    169. 78
    170. 79
    171. 80
    172. 81
    173. 82
    174. 83
    175. 84
    176. 85
    177. 86
    178. 87
    179. 88
    180. 89
    181. 90
    182. 91
    183. 92
    184. 93
    185. 94
    186. 95
    187. 96
    188. 97
    189. 下面是测试实例代码:

    190.     AcGeMatrix3d matxTran; //平移矩阵
    191.         AcGeMatrix3d matxScale;// 缩放矩阵
    192.        
    193.         AcGeMatrix3d matxRota;// 旋转矩阵
    194.     matxRota.setToRotation(30,AcGeVector3d::kZAxis);
    195.    
    196.         MatrixVector stuMatrix;
    197.         AcGePoint3d ptPos1 = AcGePoint3d(2,2,2);
    198.         AcGePoint3d ptPos2 = AcGePoint3d(2,2,2);

    199.         AcGeVector3d vecTran = AcGeVector3d(1,2,3);

    200.         matxTran.setToTranslation(vecTran);
    201.         stuMatrix = ConverMatrix(matxTran);
    202.     //此时平移矩阵matxTran
    203.         {
    204.           1   0   0   1
    205.           0   1   0   2
    206.           0   0   1   3
    207.           0   0   0   1
    208.     }
    209.    
    210.         matxScale.setToScaling(3);
    211.         stuMatrix = ConverMatrix(matxScale);
    212.      //此时缩放矩阵matxScale
    213.         {
    214.            3   0   0   0
    215.            0   3   0   0
    216.            0   0   3   0
    217.            0   0   0   1
    218.     }
    219.    
    220.         ptPos1.transformBy(matxTran);
    221.         ptPos1.transformBy(matxScale);

    222.         //--------
    223.         AcGeMatrix3d matrxTop = matxScale * matxTran; // 先平移再缩放矩阵
    224.         ptPos2.transformBy(matrxTop);

    225.         // 验证结果ptPos1和ptPos2是一样的等于(9,12,15);
    226.        

    227.         int nTrans = 3;
    228.         AcGeMatrix3d matxExp1;
    229.         AcGeMatrix3d matxExp2;
    230.         matxExp2 = matxExp1.setTranslation(nTrans * AcGeVector3d::kZAxis);
    231.         matxExp2 = matxExp1.setToTranslation(nTrans * AcGeVector3d::kZAxis);
    232.         //两个函数效果一样,此时matxExp1和matxExp2的值是一样的,都是
    233.         {
    234.          1  0   0   0
    235.          0  1   0   0
    236.          0  0   1   3
    237.          0  0   0   1
    238.         }
    239. 1
    240. 2
    241. 3
    242. 4
    243. 5
    244. 6
    245. 7
    246. 8
    247. 9
    248. 10
    249. 11
    250. 12
    251. 13
    252. 14
    253. 15
    254. 16
    255. 17
    256. 18
    257. 19
    258. 20
    259. 21
    260. 22
    261. 23
    262. 24
    263. 25
    264. 26
    265. 27
    266. 28
    267. 29
    268. 30
    269. 31
    270. 32
    271. 33
    272. 34
    273. 35
    274. 36
    275. 37
    276. 38
    277. 39
    278. 40
    279. 41
    280. 42
    281. 43
    282. 44
    283. 45
    284. 46
    285. 47
    286. 48
    287. 49
    288. 50
    289. 51
    290. 52
    291. 53
    292. 54
    293. 实现不同方向X Y Z 上缩放比例不同的情况,例如 X方向缩放1倍,Y方向缩放2倍,Z方向缩放3倍:

    294.     MatrixVector stuMatrix;
    295.         stuMatrix.nM11 = 1;
    296.         stuMatrix.nM22 = 2;
    297.         stuMatrix.nM33 = 3;

    298.         //X Y Z 方向缩放不同的矩阵
    299.         AcGeMatrix3d matxScale = ConverMatrixVector(stuMatrix);

    300.         AcGePoint3d ptPos1 = AcGePoint3d(2,2,2);

    301.         ptPos1.transformBy(matxScale);
    302.         ptPos1 = (2,4,6);
    303. 1
    304. 2
    305. 3
    306. 4
    307. 5
    308. 6
    309. 7
    310. 8
    311. 9
    312. 10
    313. 11
    314. 12
    315. 如何把矩阵转换成对应的位移、旋转角度和缩放比例?

    316. AcGeMatrix3d tran = m_matrix;
    317. CHCVec3d transLation;
    318. CHCVec3d scale;
    319. CHCVec4d rotate;
    320. GetMatrixData(rotate,scale,transLation,tran);

    321. bool GetMatrixData(CHCVec4d &rVec4d,CHCVec3d &scale3d,CHCVec3d &trans3d,::AcGeMatrix3d mat)
    322. {
    323.         //平移------
    324.         trans3d.x = mat.entry[0][3];
    325.         trans3d.y = mat.entry[1][3];
    326.         trans3d.z = mat.entry[2][3];
    327.         //----------------------------------------
    328.         ::AcGeVector3d vec1(mat.entry[0][0],mat.entry[1][0],mat.entry[2][0]);
    329.         ::AcGeVector3d vec2(mat.entry[0][1],mat.entry[1][1],mat.entry[2][1]);
    330.         ::AcGeVector3d vec3(mat.entry[0][2],mat.entry[1][2],mat.entry[2][2]);

    331.         //缩放---------------------------------------
    332.         scale3d.x = vec1.length();
    333.         scale3d.y = vec2.length();
    334.         scale3d.z = vec3.length();
    335.         //------------------------------------------------

    336.         if (scale3d.x != 0)
    337.         {
    338.                 vec1.x = vec1.x/scale3d.x;
    339.                 vec1.y = vec1.y/scale3d.x;
    340.                 vec1.z = vec1.z/scale3d.x;
    341.         }

    342.         if (scale3d.y != 0)
    343.         {
    344.                 vec2.x = vec2.x/scale3d.y;
    345.                 vec2.y = vec2.y/scale3d.y;
    346.                 vec2.z = vec2.z/scale3d.y;
    347.         }

    348.         if (scale3d.z != 0)
    349.         {
    350.                 vec3.x = vec3.x/scale3d.z;
    351.                 vec3.y = vec3.y/scale3d.z;
    352.                 vec3.z = vec3.z/scale3d.z;
    353.         }

    354.         //旋转-------------------------
    355.         AcGeMatrix2d mat2d;  //旋转矩阵

    356.         mat2d.entry[0][0] = vec1.x;
    357.         mat2d.entry[1][0] = vec1.y;
    358.         mat2d.entry[2][0] = vec1.z;

    359.         mat2d.entry[0][1] = vec2.x;
    360.         mat2d.entry[1][1] = vec2.y;
    361.         mat2d.entry[2][1] = vec2.z;

    362.         mat2d.entry[0][2] = vec3.x;
    363.         mat2d.entry[1][2] = vec3.y;
    364.         mat2d.entry[2][2] = vec3.z;
    365.         //-------------------------------------------------
    366.        
    367.         rVec4d = FromRotationMatrix(mat2d);

    368.         return true;
    369. }
    370. CHCVec4d FromRotationMatrix (const AcGeMatrix2d& kRot)
    371. {
    372.         CHCVec4d quaternion;
    373.         // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
    374.         // article "Quaternion Calculus and Fast Animation".

    375.         double fTrace = kRot.entry[0][0]+kRot.entry[1][1]+kRot.entry[2][2];
    376.         double fRoot = 0.0;

    377.         if ( fTrace > 0.0 )
    378.         {
    379.                 // |w| > 1/2, may as well choose w > 1/2
    380.                 fRoot = sqrt(fTrace + 1.0f);  // 2w
    381.                 quaternion.w = 0.5f*fRoot;
    382.                 fRoot = 0.5f/fRoot;  // 1/(4w)
    383.                 quaternion.x = (kRot.entry[2][1]-kRot.entry[1][2])*fRoot;
    384.                 quaternion.y = (kRot.entry[0][2]-kRot.entry[2][0])*fRoot;
    385.                 quaternion.z = (kRot.entry[1][0]-kRot.entry[0][1])*fRoot;
    386.         }
    387.         else
    388.         {
    389.                 // |w| <= 1/2
    390.                 static size_t s_iNext[3] = { 1, 2, 0 };
    391.                 size_t i = 0;
    392.                 if ( kRot.entry[1][1] > kRot.entry[0][0] )
    393.                         i = 1;
    394.                 if ( kRot.entry[2][2] > kRot.entry[i][i] )
    395.                         i = 2;
    396.                 size_t j = s_iNext[i];
    397.                 size_t k = s_iNext[j];

    398.                 fRoot = sqrt(kRot.entry[i][i]-kRot.entry[j][j]-kRot.entry[k][k] + 1.0f);
    399.                 double* apkQuat[3] = { &quaternion.x, &quaternion.y, &quaternion.z };
    400.                 *apkQuat[i] = 0.5f*fRoot;
    401.                 fRoot = 0.5f/fRoot;
    402.                 quaternion.w = (kRot.entry[k][j]-kRot.entry[j][k])*fRoot;
    403.                 *apkQuat[j] = (kRot.entry[j][i]+kRot.entry[i][j])*fRoot;
    404.                 *apkQuat[k] = (kRot.entry[k][i]+kRot.entry[i][k])*fRoot;
    405.         }

    406.         return quaternion;
    407. }

    408. 1
    409. 2
    410. 3
    411. 4
    412. 5
    413. 6
    414. 7
    415. 8
    416. 9
    417. 10
    418. 11
    419. 12
    420. 13
    421. 14
    422. 15
    423. 16
    424. 17
    425. 18
    426. 19
    427. 20
    428. 21
    429. 22
    430. 23
    431. 24
    432. 25
    433. 26
    434. 27
    435. 28
    436. 29
    437. 30
    438. 31
    439. 32
    440. 33
    441. 34
    442. 35
    443. 36
    444. 37
    445. 38
    446. 39
    447. 40
    448. 41
    449. 42
    450. 43
    451. 44
    452. 45
    453. 46
    454. 47
    455. 48
    456. 49
    457. 50
    458. 51
    459. 52
    460. 53
    461. 54
    462. 55
    463. 56
    464. 57
    465. 58
    466. 59
    467. 60
    468. 61
    469. 62
    470. 63
    471. 64
    472. 65
    473. 66
    474. 67
    475. 68
    476. 69
    477. 70
    478. 71
    479. 72
    480. 73
    481. 74
    482. 75
    483. 76
    484. 77
    485. 78
    486. 79
    487. 80
    488. 81
    489. 82
    490. 83
    491. 84
    492. 85
    493. 86
    494. 87
    495. 88
    496. 89
    497. 90
    498. 91
    499. 92
    500. 93
    501. 94
    502. 95
    503. 96
    504. 97
    505. 98
    506. 99
    507. 100
    508. 101
    509. 102
    510. 103
    511. 104
    512. 105
    513. 106
    514. 107
    515. 3、世界坐标变换要先缩放、后旋转、再平移的原因
    516.   一个三维场景中的各个模型一般需要各自建模,再通过坐标变换放到一个统一的世界空间的指定位置上。 这个过程在 3D 图形学中称作“世界变换” 。 世界变换有三种,平移、旋转和缩放 (实际还有不常用的扭曲和镜像,它们不是affine变换)。 这三种变换按各种顺序执行,结果是不同的。 可是实际的应用中一般按照 缩放 -> 旋转 -> 平移的顺序进行。 这样做的原因是可以获得最符合常理的变换结果。

    517. 比方说,通过世界变换希望获得的结果可能是:

    518. 将一个放在原点的物体(比方说可乐罐)移动到(30,50),让它自身倾斜 45 度,
    519. 再放大 2 倍。
    520. 1
    521. 2
    522. 而不希望的结果是:
    523. 1.和本地坐标轴成角度的缩放(会导致扭曲,像踩扁的可乐罐)。
    524. 2.绕自己几何中心以外位置的原点的旋转 (地球公转式) 和缩放。

    525. 而颠倒了上述变换顺序就会得到这样不自然的结果。
    526. 具体的说:
    527. 当缩放在旋转之后进行时,会发生现象1。
    528. 当缩放和旋转在平移之后进行时会发生现象2。

    529. 这是因为:在物体刚刚放入世界坐标系的时候使用的是本地坐标,也就是本地和全局坐标系的原点和坐标轴都是重合的(当然两者分别使用了左右手坐标系时除外 - 那是BUG),此时所有物体都“把世界坐标系当做自己的本地坐标系”。
    530. 而经过了坐标变换之后:
    531. 1.缩放变换不改变坐标轴的走向,也不改变原点的位置,所以两个坐标系仍然重合。
    532. 2.旋转变换改变坐标轴的走向,但不改变原点的位置,所以两个坐标系坐标轴不再处于相同走向。
    533. 3.平移变换不改变坐标轴走向,但改变原点位置,两个坐标系原点不再重合。
    534. 这样就可以解释问什么缩放不能在旋转之后,而缩放和旋转都不能在平移之后了。 于是没有问题的顺序只能是 缩放 -> 旋转 -> 平移 。
    复制代码
    回复


    http://www.mjgw.org/ 专业从事膜结构设计、制作加工、施工安装的膜结构工程服务,能够为客户提供专业的膜结构整体解决方案。做中国最好的膜结构综合服务平台。欢迎大家联系电话:198-7840-1958,QQ:463017170.
    相关关键词:膜结构车棚,膜结构车棚覆盖,膜结构车棚公司,膜结构车棚多少钱,膜结构车棚厂家,膜结构车棚价格,社区膜结构车棚,膜结构车棚膜布厂家 ,膜结构车棚哪家好,膜结构车棚多少钱一米,膜结构车棚报价,膜结构车棚哪里有,膜结构车棚定制,膜结构车棚安装,膜结构车棚设计,膜结构车棚电话,膜结构车棚加工,膜结构车棚膜布价格,膜结构车棚批发,膜结构车棚制造商,膜结构车棚生产厂家,膜结构车棚设计,膜结构车棚施工,膜结构车棚多少钱一平米,膜结构车棚订制,张拉膜车棚,张拉膜车棚覆盖,张拉膜车棚公司,张拉膜车棚多少钱,张拉膜车棚厂家,张拉膜车棚价格,社区张拉膜车棚,张拉膜车棚膜布厂家 ,张拉膜车棚哪家好,张拉膜车棚多少钱一米,张拉膜车棚报价,张拉膜车棚哪里有,张拉膜车棚定制,张拉膜车棚安装,张拉膜车棚设计,张拉膜车棚电话,张拉膜车棚加工,张拉膜车棚膜布价格,张拉膜车棚批发,张拉膜车棚制造商,张拉膜车棚生产厂家,张拉膜车棚设计,张拉膜车棚施工,张拉膜车棚多少钱一平米,张拉膜车棚订制,常用膜材品牌:德国杜肯、法国法拉利、德国海德斯、德国米乐、日本平岗、韩国秀博、比利时希运、美国赫虏伯、中国科宝、上海慧遥。

    使用道具 举报

  • TA的每日心情
    开心
    2021-6-19 14:40
  • 签到天数: 1539 天

    [LV.Master]伴坛终老

     楼主| 发表于 2020-12-29 15:45 | 显示全部楼层
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    推荐膜材品牌上一条 /6 下一条

    进口膜材 国产膜材 pvdf膜材ptfe膜材ETFE膜材
    最好的膜结构公司 一级膜结构资质 膜结构一级资质
    膜结构设计-膜结构十大品牌-etfe设计-充气膜结构
    诺科膜结构
    遨都膜结构设计
    中国膜结构网
    中国空间膜结构

    QQ|申请友链|手机版|中国膜结构论坛