Rodrigues绕任意轴旋转

huangapple go评论91阅读模式
英文:

Rodrigues Rotation about an arbitrary axis

问题

Sure, here's the translated code:

  1. 假设我有一个候选向量 `v(vx, vy, vz)`。我想围绕起始向量 `s(sx,sy,sz)` 到结束向量 `e(ex, ey, ez)` 的任意轴旋转 `theta` 度,当坐标轴的原点位于 `o(ox, oy, oz)` 处时。
  2. 因此,在以下源代码中,我正在执行**罗德里格斯旋转**,但结果不正确:
  3. ```C#
  4. public class RotoTranslation
  5. {
  6. private readonly Vec3 origin;
  7. private readonly double cosTheta;
  8. private readonly double sinTheta;
  9. private readonly Vec3 axis;
  10. private readonly Matrix3x3 rotationMatrix;
  11. private readonly Matrix3x3 translationMatrix;
  12. private readonly Matrix3x3 invTranslationMatrix;
  13. public RotoTranslation(
  14. Vec3 origin,
  15. Vec3 start,
  16. Vec3 end,
  17. double angle_rad)
  18. {
  19. this.origin = origin;
  20. this.axis = Vec3.Normalize(end - start);
  21. this.cosTheta = Math.Cos(angle_rad);
  22. this.sinTheta = Math.Sin(angle_rad);
  23. Matrix3x3 uOuter =
  24. Vec3.OuterProduct_mat(axis, axis);
  25. Matrix3x3 uCross =
  26. new Matrix3x3(0.0f, -axis.z, axis.y,
  27. axis.z, 0.0f, -axis.x,
  28. -axis.y, axis.x, 0.0f);
  29. rotationMatrix =
  30. cosTheta * Matrix3x3.Identity()
  31. + (1.0f - cosTheta) * uOuter
  32. + sinTheta * uCross;
  33. translationMatrix =
  34. Matrix3x3.CreateTranslation(-origin);
  35. rotationMatrix =
  36. rotationMatrix * translationMatrix;
  37. invTranslationMatrix =
  38. Matrix3x3.CreateTranslation(origin);
  39. }
  40. public Vec3 RotateVector(Vec3 vector)
  41. {
  42. Vec3 transformedVector =
  43. Vec3.TransformNormal(
  44. vector - origin,
  45. rotationMatrix);
  46. return Vec3.Transform(
  47. transformedVector,
  48. invTranslationMatrix);
  49. }
  50. }

测试

  1. [TestMethod]
  2. public void TestMethod1()
  3. {
  4. Vec3 origin = new Vec3(1, 1, 1);
  5. Vec3 start = new Vec3(1, 1, 1);
  6. Vec3 end = new Vec3(4, 4, 4);
  7. Vec3 candidate = new Vec3(3,3,3);
  8. double degrees = 360;
  9. degrees = degrees * (Math.PI / 180.0);
  10. RotoTranslation rot =
  11. new RotoTranslation(origin,
  12. start,
  13. end,
  14. degrees);
  15. Vec3 rotated = rot.RotateVector(candidate);
  16. Assert.AreEqual(candidate[0], rotated[0]);
  17. Assert.AreEqual(candidate[1], rotated[1]);
  18. Assert.AreEqual(candidate[2], rotated[2]);
  19. }

如果我围绕轴旋转一个向量360度,它应该位于初始向量的相同位置。然而,在这里并非如此。

你能告诉我哪里出错了吗?

N.B. 我必须使用 Matrix3x3,而不是 Matrix4x4(增广矩阵)。

  1. 请注意,这是代码的翻译部分,如果你需要任何其他帮助或有其他问题,请告诉我。
  2. <details>
  3. <summary>英文:</summary>
  4. Suppose, I have a candidate vector `v(vx, vy, vz)`. I want to rotate it `theta` degrees about an arbitrary axis that starts at vector `s(sx,sy,sz)` and ends at vector `e(ex, ey, ez)` when the origin of the axes is located at `o(ox, oy, oz)`.
  5. So, I am doing the **Rodrigues rotation** in the following source code, but it is not giving the correct results:
  6. ```C#
  7. public class RotoTranslation
  8. {
  9. private readonly Vec3 origin;
  10. private readonly double cosTheta;
  11. private readonly double sinTheta;
  12. private readonly Vec3 axis;
  13. private readonly Matrix3x3 rotationMatrix;
  14. private readonly Matrix3x3 translationMatrix;
  15. private readonly Matrix3x3 invTranslationMatrix;
  16. public RotoTranslation(
  17. Vec3 origin,
  18. Vec3 start,
  19. Vec3 end,
  20. double angle_rad)
  21. {
  22. this.origin = origin;
  23. this.axis = Vec3.Normalize(end - start);
  24. this.cosTheta = Math.Cos(angle_rad);
  25. this.sinTheta = Math.Sin(angle_rad);
  26. Matrix3x3 uOuter =
  27. Vec3.OuterProduct_mat(axis, axis);
  28. Matrix3x3 uCross =
  29. new Matrix3x3(0.0f, -axis.z, axis.y,
  30. axis.z, 0.0f, -axis.x,
  31. -axis.y, axis.x, 0.0f);
  32. rotationMatrix =
  33. cosTheta * Matrix3x3.Identity()
  34. + (1.0f - cosTheta) * uOuter
  35. + sinTheta * uCross;
  36. translationMatrix =
  37. Matrix3x3.CreateTranslation(-origin);
  38. rotationMatrix =
  39. rotationMatrix * translationMatrix;
  40. invTranslationMatrix =
  41. Matrix3x3.CreateTranslation(origin);
  42. }
  43. public Vec3 RotateVector(Vec3 vector)
  44. {
  45. Vec3 transformedVector =
  46. Vec3.TransformNormal(
  47. vector - origin,
  48. rotationMatrix);
  49. return Vec3.Transform(
  50. transformedVector,
  51. invTranslationMatrix);
  52. }
  53. }

Test

  1. [TestMethod]
  2. public void TestMethod1()
  3. {
  4. Vec3 origin = new Vec3(1, 1, 1);
  5. Vec3 start = new Vec3(1, 1, 1);
  6. Vec3 end = new Vec3(4, 4, 4);
  7. Vec3 candidate = new Vec3(3,3,3);
  8. double degrees = 360;
  9. degrees = degrees * (Math.PI / 180.0);
  10. RotoTranslation rot =
  11. new RotoTranslation(origin,
  12. start,
  13. end,
  14. degrees);
  15. Vec3 rotated = rot.RotateVector(candidate);
  16. Assert.AreEqual(candidate[0], rotated[0]);
  17. Assert.AreEqual(candidate[1], rotated[1]);
  18. Assert.AreEqual(candidate[2], rotated[2]);
  19. }

If I rotate a vector around an axis 360 degrees, it should be at the same position as the initial vector. However, that is not the case here.

Can you tell me what I am doing wrong?

N.B. I must use Matrix3x3, rather than a Matrix4x4 (augmented matrix).


Full Source code

  1. using System;
  2. using System.Collections.Generic;
  3. using Microsoft.VisualStudio.TestTools.UnitTesting;
  4. public class Vec3
  5. {
  6. public double x, y, z;
  7. public Vec3(double x, double y, double z)
  8. {
  9. this.x = x;
  10. this.y = y;
  11. this.z = z;
  12. }
  13. public static double DistanceSquared(Vec3 t1, Vec3 t2)
  14. {
  15. double x = t1.x - t2.x;
  16. double y = t1.y - t2.y;
  17. double z = t1.z - t2.z;
  18. return x * x + y * y + z * z;
  19. }
  20. public static double Distance(Vec3 t1, Vec3 t2)
  21. {
  22. if (t1 == null) throw new Exception(&quot;point1 is null&quot;);
  23. if (t2 == null) throw new Exception(&quot;point2 is null&quot;);
  24. return Math.Sqrt(DistanceSquared(t1, t2));
  25. }
  26. public Vec3 Subtract(Vec3 rhs)
  27. {
  28. return new Vec3(this.x - rhs.x, this.y - rhs.y, this.z - rhs.z);
  29. }
  30. public static Vec3 operator -(Vec3 a, Vec3 b)
  31. {
  32. return new Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
  33. }
  34. public Vec3 Scale(double rhs)
  35. {
  36. return new Vec3(this.x * rhs, this.y * rhs, this.z * rhs);
  37. }
  38. public double MagnitudeSquared()
  39. {
  40. return this.x * this.x + this.y * this.y + this.z * this.z;
  41. }
  42. public static double Dot(Vec3 a, Vec3 b)
  43. {
  44. return a.x * b.x + a.y * b.y + a.z * b.z;
  45. }
  46. public Vec3 Cross(Vec3 other)
  47. {
  48. double a = this.y * other.z - this.z * other.y;
  49. double b = this.z * other.x - this.x * other.z;
  50. double c = this.x * other.y - this.y * other.x;
  51. return new Vec3(a, b, c);
  52. }
  53. public override string ToString()
  54. {
  55. return $&quot;{x,8:0.000}{y,8:0.000}{z,8:0.000}&quot;;
  56. }
  57. public Vec3(string x, string y, string z)
  58. {
  59. this.x = Convert.ToDouble(x);
  60. this.y = Convert.ToDouble(y);
  61. this.z = Convert.ToDouble(z);
  62. }
  63. public Vec3(string xyz)
  64. {
  65. string[] vals = xyz.Split(new char[] { &#39; &#39; }, StringSplitOptions.RemoveEmptyEntries);
  66. this.x = Convert.ToDouble(vals[0].Trim());
  67. this.y = Convert.ToDouble(vals[1].Trim());
  68. this.z = Convert.ToDouble(vals[2].Trim());
  69. }
  70. public Vec3()
  71. {
  72. }
  73. public static Vec3 Normalize(Vec3 vec)
  74. {
  75. double mag = Math.Sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z);
  76. return new Vec3(vec.x / mag, vec.y / mag, vec.z / mag);
  77. }
  78. public static Vec3 OuterProduct(Vec3 a, Vec3 b)
  79. {
  80. double x = a.y * b.z - a.z * b.y;
  81. double y = a.z * b.x - a.x * b.z;
  82. double z = a.x * b.y - a.y * b.x;
  83. return new Vec3(x, y, z);
  84. }
  85. public static Matrix3x3 OuterProduct_mat(Vec3 lhs, Vec3 rhs)
  86. {
  87. double[,] data = new double[3, 3];
  88. data[0, 0] = lhs.x * rhs.x;
  89. data[0, 1] = lhs.x * rhs.y;
  90. data[0, 2] = lhs.x * rhs.z;
  91. data[1, 0] = lhs.y * rhs.x;
  92. data[1, 1] = lhs.y * rhs.y;
  93. data[1, 2] = lhs.y * rhs.z;
  94. data[2, 0] = lhs.z * rhs.x;
  95. data[2, 1] = lhs.z * rhs.y;
  96. data[2, 2] = lhs.z * rhs.z;
  97. return new Matrix3x3(data[0, 0], data[0, 1], data[0, 2],
  98. data[1, 0], data[1, 1], data[1, 2],
  99. data[2, 0], data[2, 1], data[2, 2]);
  100. }
  101. public static Vec3 operator -(Vec3 v)
  102. {
  103. return new Vec3(-v.x, -v.y, -v.z);
  104. }
  105. public static Vec3 Transform(Vec3 v, Matrix3x3 m)
  106. {
  107. double x = m[0] * v.x + m[1] * v.y + m[2] * v.z;
  108. double y = m[3] * v.x + m[4] * v.y + m[5] * v.z;
  109. double z = m[6] * v.x + m[7] * v.y + m[8] * v.z;
  110. return new Vec3(x, y, z);
  111. }
  112. public static Vec3 TransformNormal(Vec3 normal, Matrix3x3 matrix)
  113. {
  114. return new Vec3(
  115. matrix[0] * normal.x + matrix[3] * normal.y + matrix[6] * normal.z,
  116. matrix[1] * normal.x + matrix[4] * normal.y + matrix[7] * normal.z,
  117. matrix[2] * normal.x + matrix[5] * normal.y + matrix[8] * normal.z
  118. );
  119. }
  120. public static Vec3 operator +(Vec3 v1, Vec3 v2)
  121. {
  122. return new Vec3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
  123. }
  124. public double this[int i]
  125. {
  126. get
  127. {
  128. switch (i)
  129. {
  130. case 0:
  131. return x;
  132. case 1:
  133. return y;
  134. case 2:
  135. return z;
  136. default:
  137. throw new IndexOutOfRangeException();
  138. }
  139. }
  140. set
  141. {
  142. switch (i)
  143. {
  144. case 0:
  145. x = value;
  146. break;
  147. case 1:
  148. y = value;
  149. break;
  150. case 2:
  151. z = value;
  152. break;
  153. default:
  154. throw new IndexOutOfRangeException();
  155. }
  156. }
  157. }
  158. }
  159. public class Matrix3x3
  160. {
  161. const int rows = 3;
  162. const int cols = 3;
  163. private List&lt;double&gt; data2d;
  164. public Matrix3x3()
  165. {
  166. data2d = new List&lt;double&gt;(new double[rows * cols]);
  167. }
  168. public Matrix3x3(double x1, double y1, double z1,
  169. double x2, double y2, double z2,
  170. double x3, double y3, double z3)
  171. {
  172. data2d = new List&lt;double&gt;(new double[rows * cols]);
  173. data2d[0] = x1; data2d[1] = y1; data2d[2] = z1;
  174. data2d[3] = x2; data2d[4] = y2; data2d[5] = z2;
  175. data2d[6] = x3; data2d[7] = y3; data2d[8] = z3;
  176. }
  177. public double this[int i]
  178. {
  179. get { return data2d[i]; }
  180. set { data2d[i] = value; }
  181. }
  182. public static Matrix3x3 Add(Matrix3x3 lhs, Matrix3x3 rhs)
  183. {
  184. Matrix3x3 result = new Matrix3x3();
  185. for (int i = 0; i &lt; rows * cols; i++)
  186. {
  187. result[i] = lhs[i] + rhs[i];
  188. }
  189. return result;
  190. }
  191. public static Matrix3x3 Sub(Matrix3x3 lhs, Matrix3x3 rhs)
  192. {
  193. Matrix3x3 result = new Matrix3x3();
  194. for (int i = 0; i &lt; rows * cols; i++)
  195. {
  196. result[i] = lhs[i] - rhs[i];
  197. }
  198. return result;
  199. }
  200. public static Matrix3x3 mul_scalar(Matrix3x3 lhs, double rhs)
  201. {
  202. Matrix3x3 result = new Matrix3x3();
  203. for (int i = 0; i &lt; rows * cols; i++)
  204. {
  205. result[i] = lhs[i] * rhs;
  206. }
  207. return result;
  208. }
  209. public static Matrix3x3 div_scalar(Matrix3x3 lhs, double rhs)
  210. {
  211. Matrix3x3 result = new Matrix3x3();
  212. for (int i = 0; i &lt; rows * cols; i++)
  213. {
  214. result[i] = lhs[i] / rhs;
  215. }
  216. return result;
  217. }
  218. public static Vec3 mul_vec_mut(Matrix3x3 lhs, Vec3 rhs)
  219. {
  220. double x = lhs[0] * rhs.x + lhs[1] * rhs.y + lhs[2] * rhs.z;
  221. double y = lhs[3] * rhs.x + lhs[4] * rhs.y + lhs[5] * rhs.z;
  222. double z = lhs[6] * rhs.x + lhs[7] * rhs.y + lhs[8] * rhs.z;
  223. return new Vec3(x, y, z);
  224. }
  225. public double det()
  226. {
  227. Matrix3x3 lhs = this;
  228. double a = lhs[0] * (lhs[4] * lhs[8] - lhs[5] * lhs[7]);
  229. double b = lhs[1] * (lhs[3] * lhs[8] - lhs[5] * lhs[6]);
  230. double c = lhs[2] * (lhs[3] * lhs[7] - lhs[4] * lhs[6]);
  231. double returns = a - b + c;
  232. return returns;
  233. }
  234. public static Matrix3x3 mul_mat_mut(Matrix3x3 lhs, Matrix3x3 rhs)
  235. {
  236. Matrix3x3 result = new Matrix3x3(
  237. lhs[0] * rhs[0] + lhs[1] * rhs[3] + lhs[2] * rhs[6], // row 1, column 1
  238. lhs[0] * rhs[1] + lhs[1] * rhs[4] + lhs[2] * rhs[7], // row 1, column 2
  239. lhs[0] * rhs[2] + lhs[1] * rhs[5] + lhs[2] * rhs[8], // row 1, column 3
  240. lhs[3] * rhs[0] + lhs[4] * rhs[3] + lhs[5] * rhs[6], // row 2, column 1
  241. lhs[3] * rhs[1] + lhs[4] * rhs[4] + lhs[5] * rhs[7], // row 2, column 2
  242. lhs[3] * rhs[2] + lhs[4] * rhs[5] + lhs[5] * rhs[8], // row 2, column 3
  243. lhs[6] * rhs[0] + lhs[7] * rhs[3] + lhs[8] * rhs[6], // row 3, column 1
  244. lhs[6] * rhs[1] + lhs[7] * rhs[4] + lhs[8] * rhs[7], // row 3, column 2
  245. lhs[6] * rhs[2] + lhs[7] * rhs[5] + lhs[8] * rhs[8]); // row 3, column 3
  246. return result;
  247. }
  248. public static Matrix3x3 inverse(Matrix3x3 lhs)
  249. {
  250. Matrix3x3 temp = null;
  251. double _det = lhs.det();
  252. if (_det != 0.0)
  253. {
  254. double inv_det = 1.0 / _det;
  255. temp = new Matrix3x3(
  256. lhs[4] * lhs[8] - lhs[5] * lhs[7],
  257. lhs[2] * lhs[7] - lhs[1] * lhs[8],
  258. lhs[1] * lhs[5] - lhs[2] * lhs[4],
  259. lhs[5] * lhs[6] - lhs[3] * lhs[8],
  260. lhs[0] * lhs[8] - lhs[2] * lhs[6],
  261. lhs[2] * lhs[3] - lhs[0] * lhs[5],
  262. lhs[3] * lhs[7] - lhs[4] * lhs[6],
  263. lhs[1] * lhs[6] - lhs[0] * lhs[7],
  264. lhs[0] * lhs[4] - lhs[1] * lhs[3]);
  265. }
  266. return temp;
  267. }
  268. public static Matrix3x3 Identity()
  269. {
  270. return new Matrix3x3(1.0, 0.0, 0.0,
  271. 0.0, 1.0, 0.0,
  272. 0.0, 0.0, 1.0);
  273. }
  274. public static Matrix3x3 OuterProduct(Matrix3x3 a, Matrix3x3 b)
  275. {
  276. Matrix3x3 result = new Matrix3x3();
  277. for (int i = 0; i &lt; rows; i++)
  278. {
  279. for (int j = 0; j &lt; cols; j++)
  280. {
  281. result[i * cols + j] = a[i] * b[j];
  282. }
  283. }
  284. return result;
  285. }
  286. public static Matrix3x3 operator *(Matrix3x3 lhs, double rhs)
  287. {
  288. Matrix3x3 result = new Matrix3x3();
  289. for (int i = 0; i &lt; rows * cols; i++)
  290. {
  291. result[i] = lhs[i] * rhs;
  292. }
  293. return result;
  294. }
  295. public static Matrix3x3 operator *(double lhs, Matrix3x3 rhs)
  296. {
  297. return rhs * lhs;
  298. }
  299. public static Matrix3x3 operator +(Matrix3x3 lhs, Matrix3x3 rhs)
  300. {
  301. Matrix3x3 result = new Matrix3x3();
  302. for (int i = 0; i &lt; rows * cols; i++)
  303. {
  304. result[i] = lhs[i] + rhs[i];
  305. }
  306. return result;
  307. }
  308. public static Matrix3x3 CreateTranslation(Vec3 translation)
  309. {
  310. return new Matrix3x3(
  311. 1.0f, 0.0f, 0.0f,
  312. 0.0f, 1.0f, 0.0f,
  313. translation.x, translation.y, translation.z
  314. );
  315. }
  316. public static Matrix3x3 operator *(Matrix3x3 lhs, Matrix3x3 rhs)
  317. {
  318. Matrix3x3 result = new Matrix3x3();
  319. for (int i = 0; i &lt; rows; i++)
  320. {
  321. for (int j = 0; j &lt; cols; j++)
  322. {
  323. double sum = 0;
  324. for (int k = 0; k &lt; cols; k++)
  325. {
  326. sum += lhs[i * cols + k] * rhs[k * cols + j];
  327. }
  328. result[i * cols + j] = sum;
  329. }
  330. }
  331. return result;
  332. }
  333. }
  334. public class RotoTranslation
  335. {
  336. private readonly Vec3 origin;
  337. private readonly double cosTheta;
  338. private readonly double sinTheta;
  339. private readonly Vec3 axis;
  340. private readonly Matrix3x3 rotationMatrix;
  341. private readonly Matrix3x3 translationMatrix;
  342. private readonly Matrix3x3 invTranslationMatrix;
  343. public RotoTranslation(Vec3 origin, Vec3 start, Vec3 end, double angle_rad)
  344. {
  345. this.origin = origin;
  346. this.axis = Vec3.Normalize(end - start);
  347. this.cosTheta = Math.Cos(angle_rad);
  348. this.sinTheta = Math.Sin(angle_rad);
  349. Matrix3x3 uOuter = Vec3.OuterProduct_mat(axis, axis);
  350. Matrix3x3 uCross = new Matrix3x3(
  351. 0.0f, -axis.z, axis.y,
  352. axis.z, 0.0f, -axis.x,
  353. -axis.y, axis.x, 0.0f
  354. );
  355. rotationMatrix = cosTheta * Matrix3x3.Identity()
  356. + (1.0f - cosTheta) * uOuter
  357. + sinTheta * uCross;
  358. translationMatrix = Matrix3x3.CreateTranslation(-origin);
  359. rotationMatrix = rotationMatrix * translationMatrix;
  360. invTranslationMatrix = Matrix3x3.CreateTranslation(origin);
  361. }
  362. public Vec3 RotateVector(Vec3 vector)
  363. {
  364. Vec3 transformedVector = Vec3.TransformNormal(vector - origin, rotationMatrix);
  365. return Vec3.Transform(transformedVector, invTranslationMatrix);
  366. }
  367. }
  368. [TestClass]
  369. public class RotoTranslationUnitTest
  370. {
  371. [TestMethod]
  372. public void TestMethod1()
  373. {
  374. Vec3 origin = new Vec3(1, 1, 1);
  375. Vec3 start = new Vec3(1, 1, 1);
  376. Vec3 end = new Vec3(4, 4, 4);
  377. Vec3 candidate = new Vec3(3,3,3);
  378. double degrees = 360;
  379. degrees = degrees * (Math.PI / 180.0);
  380. RotoTranslation rot = new RotoTranslation(origin, start, end, degrees);
  381. Vec3 rotated = rot.RotateVector(candidate);
  382. Assert.AreEqual(candidate[0], rotated[0]);
  383. Assert.AreEqual(candidate[1], rotated[1]);
  384. Assert.AreEqual(candidate[2], rotated[2]);
  385. }
  386. }

答案1

得分: 1

以下是翻译好的代码部分:

  1. 你的问题出在这个方法中
  2. public static Matrix3x3 CreateTranslation(Vec3 translation)
  3. {
  4. return new Matrix3x3(
  5. 1.0f, 0.0f, 0.0f,
  6. 0.0f, 1.0f, 0.0f,
  7. translation.x, translation.y, translation.z
  8. );
  9. }
  10. 要表示3D中的偏移量你需要一个4x4的矩阵排列如下
  11. | 1 0 0 x |
  12. | 0 1 0 y |
  13. | 0 0 1 z |
  14. | 0 0 0 1 |
  15. 不要使用矩阵运算处理平移只需更改代码以使用线性代数
  16. public RotoTranslation(Vec3 origin, Vec3 start, Vec3 end, double angle_rad)
  17. {
  18. this.origin = origin;
  19. this.axis = Vec3.Normalize(end - start);
  20. this.cosTheta = Math.Cos(angle_rad);
  21. this.sinTheta = Math.Sin(angle_rad);
  22. Matrix3x3 uOuter = Vec3.OuterProduct_mat(axis, axis);
  23. Matrix3x3 uCross = new Matrix3x3(
  24. 0.0f, -axis.z, axis.y,
  25. axis.z, 0.0f, -axis.x,
  26. -axis.y, axis.x, 0.0f
  27. );
  28. rotationMatrix = cosTheta * Matrix3x3.Identity()
  29. + (1.0f - cosTheta) * uOuter
  30. + sinTheta * uCross;
  31. }
  32. public Vec3 RotateVector(Vec3 vector)
  33. {
  34. Vec3 transformedVector = vector - origin;
  35. transformedVector = Vec3.Transform(transformedVector, rotationMatrix );
  36. return transformedVector + origin;
  37. }
  38. 'translationMatrix' 'InvTranslationMatrix' 不需要你已经存储了 'origin' 向量这就是你需要的一切

如果还有其他需要翻译的内容,请继续提问。

英文:

Your problem is in this method

  1. public static Matrix3x3 CreateTranslation(Vec3 translation)
  2. {
  3. return new Matrix3x3(
  4. 1.0f, 0.0f, 0.0f,
  5. 0.0f, 1.0f, 0.0f,
  6. translation.x, translation.y, translation.z
  7. );
  8. }

To represent an offset in 3D with a matrix you need a 4×4 matrix arranged as follows

  1. | 1 0 0 x |
  2. translate3(x,y,z) = | 0 1 0 y |
  3. | 0 0 1 z |
  4. | 0 0 0 1 |

Instead of handling the translation with a matrix operation, just change the code to use linear algebra

  1. public RotoTranslation(Vec3 origin, Vec3 start, Vec3 end, double angle_rad)
  2. {
  3. this.origin = origin;
  4. this.axis = Vec3.Normalize(end - start);
  5. this.cosTheta = Math.Cos(angle_rad);
  6. this.sinTheta = Math.Sin(angle_rad);
  7. Matrix3x3 uOuter = Vec3.OuterProduct_mat(axis, axis);
  8. Matrix3x3 uCross = new Matrix3x3(
  9. 0.0f, -axis.z, axis.y,
  10. axis.z, 0.0f, -axis.x,
  11. -axis.y, axis.x, 0.0f
  12. );
  13. rotationMatrix = cosTheta * Matrix3x3.Identity()
  14. + (1.0f - cosTheta) * uOuter
  15. + sinTheta * uCross;
  16. }
  17. public Vec3 RotateVector(Vec3 vector)
  18. {
  19. Vec3 transformedVector = vector - origin;
  20. transformedVector = Vec3.Transform(transformedVector, rotationMatrix );
  21. return transformedVector + origin;
  22. }

translationMatrix and InvTranslationMatrix are not needed. You have the origin vector stored and that all you need.

huangapple
  • 本文由 发表于 2023年4月17日 22:32:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76036276.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定