NumericsAssert.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Numerics;
  4. using System.Text;
  5. using NUnit.Framework;
  6. namespace SharpGLTF
  7. {
  8. // [System.Diagnostics.DebuggerStepThrough]
  9. public static class NumericsAssert
  10. {
  11. public static double UnitError(this Vector3 v) { return v.LengthError(1); }
  12. public static double LengthError(this Vector3 v, double expectedLength)
  13. {
  14. return Math.Abs(Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z) - expectedLength);
  15. }
  16. public static void IsFinite(Single value, string message = null)
  17. {
  18. // Assert.IsTrue(float.IsFinite(value), message);
  19. Assert.That(!float.IsNaN(value) && !float.IsInfinity(value), Is.True, message);
  20. }
  21. public static void IsFinite(Double value, string message = null)
  22. {
  23. // Assert.IsTrue(double.IsFinite(value), message);
  24. Assert.That(!Double.IsNaN(value) && !Double.IsInfinity(value), Is.True, message);
  25. }
  26. public static void IsFinite(Vector2 vector)
  27. {
  28. IsFinite(vector.X, "X");
  29. IsFinite(vector.Y, "Y");
  30. }
  31. public static void IsFinite(Vector3 vector)
  32. {
  33. IsFinite(vector.X, "X");
  34. IsFinite(vector.Y, "Y");
  35. IsFinite(vector.Z, "Z");
  36. }
  37. public static void IsFinite(Vector4 vector)
  38. {
  39. IsFinite(vector.X, "X");
  40. IsFinite(vector.Y, "Y");
  41. IsFinite(vector.Z, "Z");
  42. IsFinite(vector.W, "W");
  43. }
  44. public static void IsFinite(Quaternion quaternion)
  45. {
  46. IsFinite(quaternion.X, "X");
  47. IsFinite(quaternion.Y, "Y");
  48. IsFinite(quaternion.Z, "Z");
  49. IsFinite(quaternion.W, "W");
  50. }
  51. public static void IsFinite(Plane plane)
  52. {
  53. IsFinite(plane.Normal.X, "Normal.X");
  54. IsFinite(plane.Normal.Y, "Normal.Y");
  55. IsFinite(plane.Normal.Z, "Normal.Z");
  56. IsFinite(plane.D, "D");
  57. }
  58. public static void IsFinite(Matrix3x2 matrix)
  59. {
  60. IsFinite(matrix.M11, "M11");
  61. IsFinite(matrix.M12, "M12");
  62. IsFinite(matrix.M21, "M21");
  63. IsFinite(matrix.M22, "M22");
  64. IsFinite(matrix.M31, "M31");
  65. IsFinite(matrix.M32, "M32");
  66. }
  67. public static void IsFinite(Matrix4x4 matrix)
  68. {
  69. IsFinite(matrix.M11, "M11");
  70. IsFinite(matrix.M12, "M12");
  71. IsFinite(matrix.M13, "M13");
  72. IsFinite(matrix.M14, "M14");
  73. IsFinite(matrix.M21, "M21");
  74. IsFinite(matrix.M22, "M22");
  75. IsFinite(matrix.M23, "M23");
  76. IsFinite(matrix.M24, "M24");
  77. IsFinite(matrix.M31, "M31");
  78. IsFinite(matrix.M32, "M32");
  79. IsFinite(matrix.M33, "M33");
  80. IsFinite(matrix.M34, "M34");
  81. IsFinite(matrix.M41, "M41");
  82. IsFinite(matrix.M42, "M42");
  83. IsFinite(matrix.M43, "M43");
  84. IsFinite(matrix.M44, "M44");
  85. }
  86. public static void AreEqual(BigInteger expected, BigInteger actual, double tolerance = 0)
  87. {
  88. Assert.That((double)BigInteger.Abs(actual - expected), Is.EqualTo(0).Within(tolerance));
  89. }
  90. public static void AreEqual(Vector2 expected, Vector2 actual, double tolerance = 0)
  91. {
  92. Assert.Multiple(() =>
  93. {
  94. Assert.That(actual.X, Is.EqualTo(expected.X).Within(tolerance), "X");
  95. Assert.That(actual.Y, Is.EqualTo(expected.Y).Within(tolerance), "Y");
  96. });
  97. }
  98. public static float AreEqual(Vector3 expected, Vector3 actual, double tolerance = 0)
  99. {
  100. Assert.Multiple(() =>
  101. {
  102. Assert.That(actual.X, Is.EqualTo(expected.X).Within(tolerance), "X");
  103. Assert.That(actual.Y, Is.EqualTo(expected.Y).Within(tolerance), "Y");
  104. Assert.That(actual.Z, Is.EqualTo(expected.Z).Within(tolerance), "Z");
  105. });
  106. // get tolerance
  107. var tx = Math.Abs(expected.X - actual.X);
  108. var ty = Math.Abs(expected.Y - actual.Y);
  109. var tz = Math.Abs(expected.Z - actual.Z);
  110. return Math.Max(tx, Math.Max(ty, tz));
  111. }
  112. public static void AreEqual(Vector4 expected, Vector4 actual, double tolerance = 0)
  113. {
  114. Assert.Multiple(() =>
  115. {
  116. Assert.That(actual.X, Is.EqualTo(expected.X).Within(tolerance), "X");
  117. Assert.That(actual.Y, Is.EqualTo(expected.Y).Within(tolerance), "Y");
  118. Assert.That(actual.Z, Is.EqualTo(expected.Z).Within(tolerance), "Z");
  119. Assert.That(actual.W, Is.EqualTo(expected.W).Within(tolerance), "W");
  120. });
  121. }
  122. public static void AreEqual(Quaternion expected, Quaternion actual, double tolerance = 0)
  123. {
  124. Assert.Multiple(() =>
  125. {
  126. Assert.That(actual.X, Is.EqualTo(expected.X).Within(tolerance), "X");
  127. Assert.That(actual.Y, Is.EqualTo(expected.Y).Within(tolerance), "Y");
  128. Assert.That(actual.Z, Is.EqualTo(expected.Z).Within(tolerance), "Z");
  129. Assert.That(actual.W, Is.EqualTo(expected.W).Within(tolerance), "W");
  130. });
  131. }
  132. public static void AreEqual(Matrix4x4 expected, Matrix4x4 actual, double tolerance = 0)
  133. {
  134. Assert.Multiple(() =>
  135. {
  136. Assert.That(actual.M11, Is.EqualTo(expected.M11).Within(tolerance), "M11");
  137. Assert.That(actual.M12, Is.EqualTo(expected.M12).Within(tolerance), "M12");
  138. Assert.That(actual.M13, Is.EqualTo(expected.M13).Within(tolerance), "M13");
  139. Assert.That(actual.M14, Is.EqualTo(expected.M14).Within(tolerance), "M14");
  140. Assert.That(actual.M21, Is.EqualTo(expected.M21).Within(tolerance), "M21");
  141. Assert.That(actual.M22, Is.EqualTo(expected.M22).Within(tolerance), "M22");
  142. Assert.That(actual.M23, Is.EqualTo(expected.M23).Within(tolerance), "M23");
  143. Assert.That(actual.M24, Is.EqualTo(expected.M24).Within(tolerance), "M24");
  144. Assert.That(actual.M31, Is.EqualTo(expected.M31).Within(tolerance), "M31");
  145. Assert.That(actual.M32, Is.EqualTo(expected.M32).Within(tolerance), "M32");
  146. Assert.That(actual.M33, Is.EqualTo(expected.M33).Within(tolerance), "M33");
  147. Assert.That(actual.M34, Is.EqualTo(expected.M34).Within(tolerance), "M34");
  148. Assert.That(actual.M41, Is.EqualTo(expected.M41).Within(tolerance), "M41");
  149. Assert.That(actual.M42, Is.EqualTo(expected.M42).Within(tolerance), "M42");
  150. Assert.That(actual.M43, Is.EqualTo(expected.M43).Within(tolerance), "M43");
  151. Assert.That(actual.M44, Is.EqualTo(expected.M44).Within(tolerance), "M44");
  152. });
  153. }
  154. public static float AreGeometryicallyEquivalent(Matrix4x4 expected, Matrix4x4 actual, double tolerance = 0)
  155. {
  156. var expectedX = Vector3.Transform(Vector3.UnitX, expected);
  157. var expectedY = Vector3.Transform(Vector3.UnitY, expected);
  158. var expectedZ = Vector3.Transform(Vector3.UnitZ, expected);
  159. var actualX = Vector3.Transform(Vector3.UnitX, actual);
  160. var actualY = Vector3.Transform(Vector3.UnitY, actual);
  161. var actualZ = Vector3.Transform(Vector3.UnitZ, actual);
  162. var tx = AreEqual(expectedX, actualX, tolerance);
  163. var ty = AreEqual(expectedY, actualY, tolerance);
  164. var tz = AreEqual(expectedZ, actualZ, tolerance);
  165. return Math.Max(tx, Math.Max(ty, tz));
  166. }
  167. public static void IsInvertible(Matrix3x2 matrix)
  168. {
  169. IsFinite(matrix);
  170. Assert.That(Matrix3x2.Invert(matrix, out Matrix3x2 inverted), Is.True);
  171. }
  172. public static void IsInvertible(Matrix4x4 matrix)
  173. {
  174. IsFinite(matrix);
  175. Assert.That(Matrix4x4.Invert(matrix, out Matrix4x4 inverted), Is.True);
  176. }
  177. public static void IsOrthogonal3x3(Matrix4x4 matrix, double tolerance = 0)
  178. {
  179. IsFinite(matrix);
  180. Assert.Multiple(() =>
  181. {
  182. Assert.That(matrix.M41, Is.EqualTo(0));
  183. Assert.That(matrix.M42, Is.EqualTo(0));
  184. Assert.That(matrix.M43, Is.EqualTo(0));
  185. Assert.That(matrix.M44, Is.EqualTo(1));
  186. });
  187. var cx = new Vector3(matrix.M11, matrix.M21, matrix.M31);
  188. var cy = new Vector3(matrix.M12, matrix.M22, matrix.M32);
  189. var cz = new Vector3(matrix.M13, matrix.M23, matrix.M33);
  190. Assert.Multiple(() =>
  191. {
  192. Assert.That(Vector3.Dot(cx, cy), Is.EqualTo(0).Within(tolerance));
  193. Assert.That(Vector3.Dot(cx, cz), Is.EqualTo(0).Within(tolerance));
  194. Assert.That(Vector3.Dot(cy, cz), Is.EqualTo(0).Within(tolerance));
  195. });
  196. }
  197. public static void Length(Vector2 actual, double length, double tolerance = 0)
  198. {
  199. IsFinite(actual);
  200. length = Math.Abs(actual.Length() - length);
  201. Assert.That(length, Is.EqualTo(0).Within(tolerance));
  202. }
  203. public static void Length(Vector3 actual, double length, double tolerance = 0)
  204. {
  205. IsFinite(actual);
  206. length = Math.Abs(actual.Length() - length);
  207. Assert.That(length, Is.EqualTo(0).Within(tolerance));
  208. }
  209. public static void Length(Vector4 actual, double length, double tolerance = 0)
  210. {
  211. IsFinite(actual);
  212. length = Math.Abs(actual.Length() - length);
  213. Assert.That(length, Is.EqualTo(0).Within(tolerance));
  214. }
  215. public static void Length(Quaternion actual, double length, double tolerance = 0)
  216. {
  217. IsFinite(actual);
  218. length = Math.Abs(actual.Length() - length);
  219. Assert.That(length, Is.EqualTo(0).Within(tolerance));
  220. }
  221. public static void IsNormalized(Vector2 actual, double tolerance = 0)
  222. {
  223. Length(actual, 1, tolerance);
  224. }
  225. public static void IsNormalized(Vector3 actual, double tolerance = 0)
  226. {
  227. Length(actual, 1, tolerance);
  228. }
  229. public static void IsNormalized(Vector4 actual, double tolerance = 0)
  230. {
  231. Length(actual, 1, tolerance);
  232. }
  233. public static void IsNormalized(Quaternion actual, double tolerance = 0)
  234. {
  235. Length(actual, 1, tolerance);
  236. }
  237. public static void InRange(BigInteger value, BigInteger min, BigInteger max)
  238. {
  239. GreaterOrEqual(value, min);
  240. LessOrEqual(value, max);
  241. }
  242. public static void InRange(Vector2 value, Vector2 min, Vector2 max)
  243. {
  244. GreaterOrEqual(value, min);
  245. LessOrEqual(value, max);
  246. }
  247. public static void InRange(Vector3 value, Vector3 min, Vector3 max)
  248. {
  249. GreaterOrEqual(value, min);
  250. LessOrEqual(value, max);
  251. }
  252. public static void InRange(Vector4 value, Vector4 min, Vector4 max)
  253. {
  254. GreaterOrEqual(value, min);
  255. LessOrEqual(value, max);
  256. }
  257. public static void Less(BigInteger arg1, BigInteger arg2)
  258. {
  259. Assert.That(arg1.CompareTo(arg2), Is.LessThan(0));
  260. }
  261. public static void Less(Vector2 arg1, Vector2 arg2)
  262. {
  263. Assert.Multiple(() =>
  264. {
  265. Assert.That(arg1.X, Is.LessThan(arg2.X), "X");
  266. Assert.That(arg1.Y, Is.LessThan(arg2.Y), "Y");
  267. });
  268. }
  269. public static void Less(Vector3 arg1, Vector3 arg2)
  270. {
  271. Assert.Multiple(() =>
  272. {
  273. Assert.That(arg1.X, Is.LessThan(arg2.X), "X");
  274. Assert.That(arg1.Y, Is.LessThan(arg2.Y), "Y");
  275. Assert.That(arg1.Z, Is.LessThan(arg2.Z), "Z");
  276. });
  277. }
  278. public static void Less(Vector4 arg1, Vector4 arg2)
  279. {
  280. Assert.Multiple(() =>
  281. {
  282. Assert.That(arg1.X, Is.LessThan(arg2.X), "X");
  283. Assert.That(arg1.Y, Is.LessThan(arg2.Y), "Y");
  284. Assert.That(arg1.Z, Is.LessThan(arg2.Z), "Z");
  285. Assert.That(arg1.W, Is.LessThan(arg2.W), "W");
  286. });
  287. }
  288. public static void LessOrEqual(BigInteger arg1, BigInteger arg2)
  289. {
  290. Assert.That(arg1.CompareTo(arg2), Is.LessThanOrEqualTo(0));
  291. }
  292. public static void LessOrEqual(Vector2 arg1, Vector2 arg2)
  293. {
  294. Assert.Multiple(() =>
  295. {
  296. Assert.That(arg1.X, Is.LessThanOrEqualTo(arg2.X), "X");
  297. Assert.That(arg1.Y, Is.LessThanOrEqualTo(arg2.Y), "Y");
  298. });
  299. }
  300. public static void LessOrEqual(Vector3 arg1, Vector3 arg2)
  301. {
  302. Assert.Multiple(() =>
  303. {
  304. Assert.That(arg1.X, Is.LessThanOrEqualTo(arg2.X), "X");
  305. Assert.That(arg1.Y, Is.LessThanOrEqualTo(arg2.Y), "Y");
  306. Assert.That(arg1.Z, Is.LessThanOrEqualTo(arg2.Z), "Z");
  307. });
  308. }
  309. public static void LessOrEqual(Vector4 arg1, Vector4 arg2)
  310. {
  311. Assert.Multiple(() =>
  312. {
  313. Assert.That(arg1.X, Is.LessThanOrEqualTo(arg2.X), "X");
  314. Assert.That(arg1.Y, Is.LessThanOrEqualTo(arg2.Y), "Y");
  315. Assert.That(arg1.Z, Is.LessThanOrEqualTo(arg2.Z), "Z");
  316. Assert.That(arg1.W, Is.LessThanOrEqualTo(arg2.W), "W");
  317. });
  318. }
  319. public static void Greater(BigInteger arg1, BigInteger arg2)
  320. {
  321. Assert.That(arg1.CompareTo(arg2), Is.GreaterThan(0));
  322. }
  323. public static void Greater(Vector2 arg1, Vector2 arg2)
  324. {
  325. Assert.That(arg1.X, Is.GreaterThan(arg2.X), "X");
  326. Assert.That(arg1.Y, Is.GreaterThan(arg2.Y), "Y");
  327. }
  328. public static void Greater(Vector3 arg1, Vector3 arg2)
  329. {
  330. Assert.Multiple(() =>
  331. {
  332. Assert.That(arg1.X, Is.GreaterThan(arg2.X), "X");
  333. Assert.That(arg1.Y, Is.GreaterThan(arg2.Y), "Y");
  334. Assert.That(arg1.Z, Is.GreaterThan(arg2.Z), "Z");
  335. });
  336. }
  337. public static void Greater(Vector4 arg1, Vector4 arg2)
  338. {
  339. Assert.Multiple(() =>
  340. {
  341. Assert.That(arg1.X, Is.GreaterThan(arg2.X), "X");
  342. Assert.That(arg1.Y, Is.GreaterThan(arg2.Y), "Y");
  343. Assert.That(arg1.Z, Is.GreaterThan(arg2.Z), "Z");
  344. Assert.That(arg1.W, Is.GreaterThan(arg2.W), "W");
  345. });
  346. }
  347. public static void GreaterOrEqual(BigInteger arg1, BigInteger arg2)
  348. {
  349. Assert.That(arg1.CompareTo(arg2), Is.GreaterThanOrEqualTo(0));
  350. }
  351. public static void GreaterOrEqual(Vector2 arg1, Vector2 arg2)
  352. {
  353. Assert.Multiple(() =>
  354. {
  355. Assert.That(arg1.X, Is.GreaterThanOrEqualTo(arg2.X), "X");
  356. Assert.That(arg1.Y, Is.GreaterThanOrEqualTo(arg2.Y), "Y");
  357. });
  358. }
  359. public static void GreaterOrEqual(Vector3 arg1, Vector3 arg2)
  360. {
  361. Assert.Multiple(() =>
  362. {
  363. Assert.That(arg1.X, Is.GreaterThanOrEqualTo(arg2.X), "X");
  364. Assert.That(arg1.Y, Is.GreaterThanOrEqualTo(arg2.Y), "Y");
  365. Assert.That(arg1.Z, Is.GreaterThanOrEqualTo(arg2.Z), "Z");
  366. });
  367. }
  368. public static void GreaterOrEqual(Vector4 arg1, Vector4 arg2)
  369. {
  370. Assert.Multiple(() =>
  371. {
  372. Assert.That(arg1.X, Is.GreaterThanOrEqualTo(arg2.X), "X");
  373. Assert.That(arg1.Y, Is.GreaterThanOrEqualTo(arg2.Y), "Y");
  374. Assert.That(arg1.Z, Is.GreaterThanOrEqualTo(arg2.Z), "Z");
  375. Assert.That(arg1.W, Is.GreaterThanOrEqualTo(arg2.W), "W");
  376. });
  377. }
  378. public static void AngleLessOrEqual(Vector2 a, Vector2 b, double radians)
  379. {
  380. var angle = (a, b).GetAngle();
  381. Assert.That(angle, Is.LessThanOrEqualTo(radians), "Angle");
  382. }
  383. public static void AngleLessOrEqual(Vector3 a, Vector3 b, double radians)
  384. {
  385. var angle = (a, b).GetAngle();
  386. Assert.That(angle, Is.LessThanOrEqualTo(radians), "Angle");
  387. }
  388. public static void AngleLessOrEqual(Quaternion a, Quaternion b, double radians)
  389. {
  390. var angle = (a, b).GetAngle();
  391. Assert.That(angle, Is.LessThanOrEqualTo(radians), "Angle");
  392. }
  393. }
  394. }