2
0

NumericsAssert.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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.IsTrue(!float.IsNaN(value) && !float.IsInfinity(value), message);
  20. }
  21. public static void IsFinite(Double value, string message = null)
  22. {
  23. // Assert.IsTrue(double.IsFinite(value), message);
  24. Assert.IsTrue(!Double.IsNaN(value) && !Double.IsInfinity(value), 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.AreEqual(0, (double)BigInteger.Abs(actual - expected), tolerance);
  89. }
  90. public static void AreEqual(Vector2 expected, Vector2 actual, double tolerance = 0)
  91. {
  92. Assert.AreEqual(expected.X, actual.X, tolerance, "X");
  93. Assert.AreEqual(expected.Y, actual.Y, tolerance, "Y");
  94. }
  95. public static float AreEqual(Vector3 expected, Vector3 actual, double tolerance = 0)
  96. {
  97. Assert.AreEqual(expected.X, actual.X, tolerance, "X");
  98. Assert.AreEqual(expected.Y, actual.Y, tolerance, "Y");
  99. Assert.AreEqual(expected.Z, actual.Z, tolerance, "Z");
  100. // get tolerance
  101. var tx = Math.Abs(expected.X - actual.X);
  102. var ty = Math.Abs(expected.Y - actual.Y);
  103. var tz = Math.Abs(expected.Z - actual.Z);
  104. return Math.Max(tx, Math.Max(ty, tz));
  105. }
  106. public static void AreEqual(Vector4 expected, Vector4 actual, double tolerance = 0)
  107. {
  108. Assert.AreEqual(expected.X, actual.X, tolerance, "X");
  109. Assert.AreEqual(expected.Y, actual.Y, tolerance, "Y");
  110. Assert.AreEqual(expected.Z, actual.Z, tolerance, "Z");
  111. Assert.AreEqual(expected.W, actual.W, tolerance, "W");
  112. }
  113. public static void AreEqual(Quaternion expected, Quaternion actual, double tolerance = 0)
  114. {
  115. Assert.AreEqual(expected.X, actual.X, tolerance, "X");
  116. Assert.AreEqual(expected.Y, actual.Y, tolerance, "Y");
  117. Assert.AreEqual(expected.Z, actual.Z, tolerance, "Z");
  118. Assert.AreEqual(expected.W, actual.W, tolerance, "W");
  119. }
  120. public static void AreEqual(Matrix4x4 expected, Matrix4x4 actual, double tolerance = 0)
  121. {
  122. Assert.AreEqual(expected.M11, actual.M11, tolerance, "M11");
  123. Assert.AreEqual(expected.M12, actual.M12, tolerance, "M12");
  124. Assert.AreEqual(expected.M13, actual.M13, tolerance, "M13");
  125. Assert.AreEqual(expected.M14, actual.M14, tolerance, "M14");
  126. Assert.AreEqual(expected.M21, actual.M21, tolerance, "M21");
  127. Assert.AreEqual(expected.M22, actual.M22, tolerance, "M22");
  128. Assert.AreEqual(expected.M23, actual.M23, tolerance, "M23");
  129. Assert.AreEqual(expected.M24, actual.M24, tolerance, "M24");
  130. Assert.AreEqual(expected.M31, actual.M31, tolerance, "M31");
  131. Assert.AreEqual(expected.M32, actual.M32, tolerance, "M32");
  132. Assert.AreEqual(expected.M33, actual.M33, tolerance, "M33");
  133. Assert.AreEqual(expected.M34, actual.M34, tolerance, "M34");
  134. Assert.AreEqual(expected.M41, actual.M41, tolerance, "M41");
  135. Assert.AreEqual(expected.M42, actual.M42, tolerance, "M42");
  136. Assert.AreEqual(expected.M43, actual.M43, tolerance, "M43");
  137. Assert.AreEqual(expected.M44, actual.M44, tolerance, "M44");
  138. }
  139. public static float AreGeometryicallyEquivalent(Matrix4x4 expected, Matrix4x4 actual, double tolerance = 0)
  140. {
  141. var expectedX = Vector3.Transform(Vector3.UnitX, expected);
  142. var expectedY = Vector3.Transform(Vector3.UnitY, expected);
  143. var expectedZ = Vector3.Transform(Vector3.UnitZ, expected);
  144. var actualX = Vector3.Transform(Vector3.UnitX, actual);
  145. var actualY = Vector3.Transform(Vector3.UnitY, actual);
  146. var actualZ = Vector3.Transform(Vector3.UnitZ, actual);
  147. var tx = AreEqual(expectedX, actualX, tolerance);
  148. var ty = AreEqual(expectedY, actualY, tolerance);
  149. var tz = AreEqual(expectedZ, actualZ, tolerance);
  150. return Math.Max(tx, Math.Max(ty, tz));
  151. }
  152. public static void IsInvertible(Matrix3x2 matrix)
  153. {
  154. IsFinite(matrix);
  155. Assert.IsTrue(Matrix3x2.Invert(matrix, out Matrix3x2 inverted));
  156. }
  157. public static void IsInvertible(Matrix4x4 matrix)
  158. {
  159. IsFinite(matrix);
  160. Assert.IsTrue(Matrix4x4.Invert(matrix, out Matrix4x4 inverted));
  161. }
  162. public static void IsOrthogonal3x3(Matrix4x4 matrix, double tolerance = 0)
  163. {
  164. IsFinite(matrix);
  165. Assert.AreEqual(0, matrix.M41);
  166. Assert.AreEqual(0, matrix.M42);
  167. Assert.AreEqual(0, matrix.M43);
  168. Assert.AreEqual(1, matrix.M44);
  169. var cx = new Vector3(matrix.M11, matrix.M21, matrix.M31);
  170. var cy = new Vector3(matrix.M12, matrix.M22, matrix.M32);
  171. var cz = new Vector3(matrix.M13, matrix.M23, matrix.M33);
  172. Assert.AreEqual(0, Vector3.Dot(cx, cy), tolerance);
  173. Assert.AreEqual(0, Vector3.Dot(cx, cz), tolerance);
  174. Assert.AreEqual(0, Vector3.Dot(cy, cz), tolerance);
  175. }
  176. public static void Length(Vector2 actual, double length, double tolerance = 0)
  177. {
  178. IsFinite(actual);
  179. length = Math.Abs(actual.Length() - length);
  180. Assert.AreEqual(0, length, tolerance);
  181. }
  182. public static void Length(Vector3 actual, double length, double tolerance = 0)
  183. {
  184. IsFinite(actual);
  185. length = Math.Abs(actual.Length() - length);
  186. Assert.AreEqual(0, length, tolerance);
  187. }
  188. public static void Length(Vector4 actual, double length, double tolerance = 0)
  189. {
  190. IsFinite(actual);
  191. length = Math.Abs(actual.Length() - length);
  192. Assert.AreEqual(0, length, tolerance);
  193. }
  194. public static void Length(Quaternion actual, double length, double tolerance = 0)
  195. {
  196. IsFinite(actual);
  197. length = Math.Abs(actual.Length() - length);
  198. Assert.AreEqual(0, length, tolerance);
  199. }
  200. public static void IsNormalized(Vector2 actual, double tolerance = 0)
  201. {
  202. Length(actual, 1, tolerance);
  203. }
  204. public static void IsNormalized(Vector3 actual, double tolerance = 0)
  205. {
  206. Length(actual, 1, tolerance);
  207. }
  208. public static void IsNormalized(Vector4 actual, double tolerance = 0)
  209. {
  210. Length(actual, 1, tolerance);
  211. }
  212. public static void IsNormalized(Quaternion actual, double tolerance = 0)
  213. {
  214. Length(actual, 1, tolerance);
  215. }
  216. public static void InRange(BigInteger value, BigInteger min, BigInteger max)
  217. {
  218. GreaterOrEqual(value, min);
  219. LessOrEqual(value, max);
  220. }
  221. public static void InRange(Vector2 value, Vector2 min, Vector2 max)
  222. {
  223. GreaterOrEqual(value, min);
  224. LessOrEqual(value, max);
  225. }
  226. public static void InRange(Vector3 value, Vector3 min, Vector3 max)
  227. {
  228. GreaterOrEqual(value, min);
  229. LessOrEqual(value, max);
  230. }
  231. public static void InRange(Vector4 value, Vector4 min, Vector4 max)
  232. {
  233. GreaterOrEqual(value, min);
  234. LessOrEqual(value, max);
  235. }
  236. public static void Less(BigInteger arg1, BigInteger arg2)
  237. {
  238. Assert.Less(arg1.CompareTo(arg2), 0);
  239. }
  240. public static void Less(Vector2 arg1, Vector2 arg2)
  241. {
  242. Assert.Less(arg1.X, arg2.X, "X");
  243. Assert.Less(arg1.Y, arg2.Y, "Y");
  244. }
  245. public static void Less(Vector3 arg1, Vector3 arg2)
  246. {
  247. Assert.Less(arg1.X, arg2.X, "X");
  248. Assert.Less(arg1.Y, arg2.Y, "Y");
  249. Assert.Less(arg1.Z, arg2.Z, "Z");
  250. }
  251. public static void Less(Vector4 arg1, Vector4 arg2)
  252. {
  253. Assert.Less(arg1.X, arg2.X, "X");
  254. Assert.Less(arg1.Y, arg2.Y, "Y");
  255. Assert.Less(arg1.Z, arg2.Z, "Z");
  256. Assert.Less(arg1.W, arg2.W, "W");
  257. }
  258. public static void LessOrEqual(BigInteger arg1, BigInteger arg2)
  259. {
  260. Assert.LessOrEqual(arg1.CompareTo(arg2), 0);
  261. }
  262. public static void LessOrEqual(Vector2 arg1, Vector2 arg2)
  263. {
  264. Assert.LessOrEqual(arg1.X, arg2.X, "X");
  265. Assert.LessOrEqual(arg1.Y, arg2.Y, "Y");
  266. }
  267. public static void LessOrEqual(Vector3 arg1, Vector3 arg2)
  268. {
  269. Assert.LessOrEqual(arg1.X, arg2.X, "X");
  270. Assert.LessOrEqual(arg1.Y, arg2.Y, "Y");
  271. Assert.LessOrEqual(arg1.Z, arg2.Z, "Z");
  272. }
  273. public static void LessOrEqual(Vector4 arg1, Vector4 arg2)
  274. {
  275. Assert.LessOrEqual(arg1.X, arg2.X, "X");
  276. Assert.LessOrEqual(arg1.Y, arg2.Y, "Y");
  277. Assert.LessOrEqual(arg1.Z, arg2.Z, "Z");
  278. Assert.LessOrEqual(arg1.W, arg2.W, "W");
  279. }
  280. public static void Greater(BigInteger arg1, BigInteger arg2)
  281. {
  282. Assert.Greater(arg1.CompareTo(arg2), 0);
  283. }
  284. public static void Greater(Vector2 arg1, Vector2 arg2)
  285. {
  286. Assert.Greater(arg1.X, arg2.X, "X");
  287. Assert.Greater(arg1.Y, arg2.Y, "Y");
  288. }
  289. public static void Greater(Vector3 arg1, Vector3 arg2)
  290. {
  291. Assert.Greater(arg1.X, arg2.X, "X");
  292. Assert.Greater(arg1.Y, arg2.Y, "Y");
  293. Assert.Greater(arg1.Z, arg2.Z, "Z");
  294. }
  295. public static void Greater(Vector4 arg1, Vector4 arg2)
  296. {
  297. Assert.Greater(arg1.X, arg2.X, "X");
  298. Assert.Greater(arg1.Y, arg2.Y, "Y");
  299. Assert.Greater(arg1.Z, arg2.Z, "Z");
  300. Assert.Greater(arg1.W, arg2.W, "W");
  301. }
  302. public static void GreaterOrEqual(BigInteger arg1, BigInteger arg2)
  303. {
  304. Assert.GreaterOrEqual(arg1.CompareTo(arg2), 0);
  305. }
  306. public static void GreaterOrEqual(Vector2 arg1, Vector2 arg2)
  307. {
  308. Assert.GreaterOrEqual(arg1.X, arg2.X, "X");
  309. Assert.GreaterOrEqual(arg1.Y, arg2.Y, "Y");
  310. }
  311. public static void GreaterOrEqual(Vector3 arg1, Vector3 arg2)
  312. {
  313. Assert.GreaterOrEqual(arg1.X, arg2.X, "X");
  314. Assert.GreaterOrEqual(arg1.Y, arg2.Y, "Y");
  315. Assert.GreaterOrEqual(arg1.Z, arg2.Z, "Z");
  316. }
  317. public static void GreaterOrEqual(Vector4 arg1, Vector4 arg2)
  318. {
  319. Assert.GreaterOrEqual(arg1.X, arg2.X, "X");
  320. Assert.GreaterOrEqual(arg1.Y, arg2.Y, "Y");
  321. Assert.GreaterOrEqual(arg1.Z, arg2.Z, "Z");
  322. Assert.GreaterOrEqual(arg1.W, arg2.W, "W");
  323. }
  324. public static void AngleLessOrEqual(Vector2 a, Vector2 b, double radians)
  325. {
  326. var angle = (a, b).GetAngle();
  327. Assert.LessOrEqual(angle, radians, "Angle");
  328. }
  329. public static void AngleLessOrEqual(Vector3 a, Vector3 b, double radians)
  330. {
  331. var angle = (a, b).GetAngle();
  332. Assert.LessOrEqual(angle, radians, "Angle");
  333. }
  334. public static void AngleLessOrEqual(Quaternion a, Quaternion b, double radians)
  335. {
  336. var angle = (a, b).GetAngle();
  337. Assert.LessOrEqual(angle, radians, "Angle");
  338. }
  339. }
  340. }