BoundingPolygon2DTest.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. // MonoGame - Copyright (C) MonoGame Foundation, Inc
  2. // This file is subject to the terms and conditions defined in
  3. // file 'LICENSE.txt', which is part of this source code package.
  4. using System;
  5. using Microsoft.Xna.Framework;
  6. namespace MonoGame.Extended.Tests
  7. {
  8. public sealed class BoundingPolygon2DTest
  9. {
  10. #region Constructor Tests
  11. [Fact]
  12. public void Constructor_Triangle()
  13. {
  14. var vertices = new[]
  15. {
  16. new Vector2(0, 0),
  17. new Vector2(10, 0),
  18. new Vector2(5, 10)
  19. };
  20. var polygon = new BoundingPolygon2D(vertices);
  21. Assert.Equal(3, polygon.VertexCount);
  22. }
  23. [Fact]
  24. public void Constructor_Square()
  25. {
  26. var vertices = new[]
  27. {
  28. new Vector2(0, 0),
  29. new Vector2(10, 0),
  30. new Vector2(10, 10),
  31. new Vector2(0, 10)
  32. };
  33. var polygon = new BoundingPolygon2D(vertices);
  34. Assert.Equal(4, polygon.VertexCount);
  35. }
  36. [Fact]
  37. public void Constructor_ThrowsWhenNull()
  38. {
  39. Assert.Throws<ArgumentNullException>(() => new BoundingPolygon2D(null));
  40. }
  41. [Fact]
  42. public void Constructor_ThrowsWhenTooFewVertices()
  43. {
  44. var vertices = new[]
  45. {
  46. new Vector2(0, 0),
  47. new Vector2(10, 0)
  48. };
  49. Assert.Throws<ArgumentException>(() => new BoundingPolygon2D(vertices));
  50. }
  51. [Fact]
  52. public void Constructor_WithNormals()
  53. {
  54. var vertices = new[]
  55. {
  56. new Vector2(0, 0),
  57. new Vector2(10, 0),
  58. new Vector2(10, 10)
  59. };
  60. var normals = new[]
  61. {
  62. new Vector2(0, -1),
  63. new Vector2(1, 0),
  64. new Vector2(-0.707f, 0.707f)
  65. };
  66. var polygon = new BoundingPolygon2D(vertices, normals);
  67. Assert.Equal(3, polygon.VertexCount);
  68. }
  69. [Fact]
  70. public void Constructor_WithNormals_ThrowsWhenNullVertices()
  71. {
  72. var normals = new[]
  73. {
  74. new Vector2(0, -1),
  75. new Vector2(1, 0),
  76. new Vector2(0, 1)
  77. };
  78. Assert.Throws<ArgumentNullException>(() => new BoundingPolygon2D(null, normals));
  79. }
  80. [Fact]
  81. public void Constructor_WithNormals_ThrowsWhenNullNormals()
  82. {
  83. var vertices = new[]
  84. {
  85. new Vector2(0, 0),
  86. new Vector2(10, 0),
  87. new Vector2(10, 10)
  88. };
  89. Assert.Throws<ArgumentNullException>(() => new BoundingPolygon2D(vertices, null));
  90. }
  91. [Fact]
  92. public void Constructor_WithNormals_ThrowsWhenLengthMismatch()
  93. {
  94. var vertices = new[]
  95. {
  96. new Vector2(0, 0),
  97. new Vector2(10, 0),
  98. new Vector2(10, 10)
  99. };
  100. var normals = new[]
  101. {
  102. new Vector2(0, -1),
  103. new Vector2(1, 0)
  104. };
  105. Assert.Throws<ArgumentException>(() => new BoundingPolygon2D(vertices, normals));
  106. }
  107. #endregion
  108. #region Computed Property Tests
  109. [Fact]
  110. public void VertexCount_ReturnsCorrectCount()
  111. {
  112. var vertices = new[]
  113. {
  114. new Vector2(0, 0),
  115. new Vector2(10, 0),
  116. new Vector2(10, 10),
  117. new Vector2(0, 10)
  118. };
  119. var polygon = new BoundingPolygon2D(vertices);
  120. Assert.Equal(4, polygon.VertexCount);
  121. }
  122. [Fact]
  123. public void Centroid_TriangleReturnsCorrectValue()
  124. {
  125. var vertices = new[]
  126. {
  127. new Vector2(0, 0),
  128. new Vector2(10, 0),
  129. new Vector2(5, 10)
  130. };
  131. var polygon = new BoundingPolygon2D(vertices);
  132. var centroid = polygon.Centroid;
  133. Assert.Equal(5, centroid.X, Collision2D.Epsilon);
  134. Assert.Equal(10.0f / 3.0f, centroid.Y, Collision2D.Epsilon);
  135. }
  136. [Fact]
  137. public void Centroid_SquareReturnsCenter()
  138. {
  139. var vertices = new[]
  140. {
  141. new Vector2(0, 0),
  142. new Vector2(10, 0),
  143. new Vector2(10, 10),
  144. new Vector2(0, 10)
  145. };
  146. var polygon = new BoundingPolygon2D(vertices);
  147. var centroid = polygon.Centroid;
  148. Assert.Equal(5, centroid.X, Collision2D.Epsilon);
  149. Assert.Equal(5, centroid.Y, Collision2D.Epsilon);
  150. }
  151. [Fact]
  152. public void Area_TriangleReturnsCorrectValue()
  153. {
  154. var vertices = new[]
  155. {
  156. new Vector2(0, 0),
  157. new Vector2(10, 0),
  158. new Vector2(5, 10)
  159. };
  160. var polygon = new BoundingPolygon2D(vertices);
  161. float area = polygon.Area;
  162. Assert.Equal(50.0f, area, Collision2D.Epsilon);
  163. }
  164. [Fact]
  165. public void Area_SquareReturnsCorrectValue()
  166. {
  167. var vertices = new[]
  168. {
  169. new Vector2(0, 0),
  170. new Vector2(10, 0),
  171. new Vector2(10, 10),
  172. new Vector2(0, 10)
  173. };
  174. var polygon = new BoundingPolygon2D(vertices);
  175. float area = polygon.Area;
  176. Assert.Equal(100.0f, area, Collision2D.Epsilon);
  177. }
  178. #endregion
  179. #region Factory Method Tests
  180. [Fact]
  181. public void CreateFromVertices()
  182. {
  183. var vertices = new[]
  184. {
  185. new Vector2(0, 0),
  186. new Vector2(10, 0),
  187. new Vector2(10, 10)
  188. };
  189. var polygon = BoundingPolygon2D.CreateFromVertices(vertices);
  190. Assert.Equal(3, polygon.VertexCount);
  191. }
  192. [Fact]
  193. public void CreateRegular_Triangle()
  194. {
  195. var center = new Vector2(5, 5);
  196. var radius = 10.0f;
  197. var sides = 3;
  198. var polygon = BoundingPolygon2D.CreateRegular(center, radius, sides);
  199. Assert.Equal(3, polygon.VertexCount);
  200. for (int i = 0; i < 3; i++)
  201. {
  202. float distance = Vector2.Distance(center, polygon.Vertices[i]);
  203. Assert.Equal(radius, distance, Collision2D.Epsilon);
  204. }
  205. }
  206. [Fact]
  207. public void CreateRegular_Square()
  208. {
  209. var center = new Vector2(0, 0);
  210. var radius = 10.0f;
  211. var sides = 4;
  212. var polygon = BoundingPolygon2D.CreateRegular(center, radius, sides);
  213. Assert.Equal(4, polygon.VertexCount);
  214. }
  215. [Fact]
  216. public void CreateRegular_Hexagon()
  217. {
  218. var center = new Vector2(0, 0);
  219. var radius = 10.0f;
  220. var sides = 6;
  221. var polygon = BoundingPolygon2D.CreateRegular(center, radius, sides);
  222. Assert.Equal(6, polygon.VertexCount);
  223. }
  224. [Fact]
  225. public void CreateRegular_WithRotation()
  226. {
  227. var center = new Vector2(0, 0);
  228. var radius = 10.0f;
  229. var sides = 4;
  230. var rotation = MathHelper.PiOver4;
  231. var polygon = BoundingPolygon2D.CreateRegular(center, radius, sides, rotation);
  232. Assert.Equal(4, polygon.VertexCount);
  233. float angle = MathHelper.PiOver4;
  234. float expectedX = radius * MathF.Cos(angle);
  235. float expectedY = radius * MathF.Sin(angle);
  236. Assert.Equal(expectedX, polygon.Vertices[0].X, Collision2D.Epsilon);
  237. Assert.Equal(expectedY, polygon.Vertices[0].Y, Collision2D.Epsilon);
  238. }
  239. [Fact]
  240. public void CreateRegular_ThrowsWhenTooFewSides()
  241. {
  242. var center = new Vector2(0, 0);
  243. var radius = 10.0f;
  244. var sides = 2;
  245. Assert.Throws<ArgumentException>(() => BoundingPolygon2D.CreateRegular(center, radius, sides));
  246. }
  247. [Fact]
  248. public void CreateFromBoundingBox2D()
  249. {
  250. var box = new BoundingBox2D(new Vector2(0, 0), new Vector2(10, 10));
  251. var polygon = BoundingPolygon2D.CreateFromBoundingBox2D(box);
  252. Assert.Equal(4, polygon.VertexCount);
  253. Assert.Contains(new Vector2(0, 0), polygon.Vertices);
  254. Assert.Contains(new Vector2(10, 0), polygon.Vertices);
  255. Assert.Contains(new Vector2(10, 10), polygon.Vertices);
  256. Assert.Contains(new Vector2(0, 10), polygon.Vertices);
  257. }
  258. [Fact]
  259. public void CreateMerged_NonOverlapping()
  260. {
  261. var vertices1 = new[]
  262. {
  263. new Vector2(0, 0),
  264. new Vector2(5, 0),
  265. new Vector2(5, 5),
  266. new Vector2(0, 5)
  267. };
  268. var polygon1 = new BoundingPolygon2D(vertices1);
  269. var vertices2 = new[]
  270. {
  271. new Vector2(10, 10),
  272. new Vector2(15, 10),
  273. new Vector2(15, 15),
  274. new Vector2(10, 15)
  275. };
  276. var polygon2 = new BoundingPolygon2D(vertices2);
  277. var merged = BoundingPolygon2D.CreateMerged(polygon1, polygon2);
  278. Assert.Equal(ContainmentType.Contains, merged.Contains(polygon1));
  279. Assert.Equal(ContainmentType.Contains, merged.Contains(polygon2));
  280. }
  281. [Fact]
  282. public void CreateMerged_Overlapping()
  283. {
  284. var vertices1 = new[]
  285. {
  286. new Vector2(0, 0),
  287. new Vector2(10, 0),
  288. new Vector2(10, 10),
  289. new Vector2(0, 10)
  290. };
  291. var polygon1 = new BoundingPolygon2D(vertices1);
  292. var vertices2 = new[]
  293. {
  294. new Vector2(5, 5),
  295. new Vector2(15, 5),
  296. new Vector2(15, 15),
  297. new Vector2(5, 15)
  298. };
  299. var polygon2 = new BoundingPolygon2D(vertices2);
  300. var merged = BoundingPolygon2D.CreateMerged(polygon1, polygon2);
  301. Assert.Equal(ContainmentType.Contains, merged.Contains(polygon1));
  302. Assert.Equal(ContainmentType.Contains, merged.Contains(polygon2));
  303. }
  304. #endregion
  305. #region Transform Tests
  306. [Fact]
  307. public void Transform_Translation()
  308. {
  309. var vertices = new[]
  310. {
  311. new Vector2(0, 0),
  312. new Vector2(10, 0),
  313. new Vector2(10, 10)
  314. };
  315. var polygon = new BoundingPolygon2D(vertices);
  316. var matrix = Matrix.CreateTranslation(5, 10, 0);
  317. var transformed = polygon.Transform(matrix);
  318. Assert.Equal(new Vector2(5, 10), transformed.Vertices[0]);
  319. Assert.Equal(new Vector2(15, 10), transformed.Vertices[1]);
  320. Assert.Equal(new Vector2(15, 20), transformed.Vertices[2]);
  321. }
  322. [Fact]
  323. public void Transform_UniformScale()
  324. {
  325. var vertices = new[]
  326. {
  327. new Vector2(0, 0),
  328. new Vector2(10, 0),
  329. new Vector2(10, 10)
  330. };
  331. var polygon = new BoundingPolygon2D(vertices);
  332. var matrix = Matrix.CreateScale(2.0f);
  333. var transformed = polygon.Transform(matrix);
  334. Assert.Equal(new Vector2(0, 0), transformed.Vertices[0]);
  335. Assert.Equal(new Vector2(20, 0), transformed.Vertices[1]);
  336. Assert.Equal(new Vector2(20, 20), transformed.Vertices[2]);
  337. }
  338. [Fact]
  339. public void Transform_Rotation()
  340. {
  341. var vertices = new[]
  342. {
  343. new Vector2(0, 0),
  344. new Vector2(10, 0),
  345. new Vector2(0, 10)
  346. };
  347. var polygon = new BoundingPolygon2D(vertices);
  348. var matrix = Matrix.CreateRotationZ(MathHelper.PiOver2);
  349. var transformed = polygon.Transform(matrix);
  350. Assert.Equal(0, transformed.Vertices[0].X, Collision2D.Epsilon);
  351. Assert.Equal(0, transformed.Vertices[0].Y, Collision2D.Epsilon);
  352. Assert.Equal(0, transformed.Vertices[1].X, Collision2D.Epsilon);
  353. Assert.Equal(10, transformed.Vertices[1].Y, Collision2D.Epsilon);
  354. Assert.Equal(-10, transformed.Vertices[2].X, Collision2D.Epsilon);
  355. Assert.Equal(0, transformed.Vertices[2].Y, Collision2D.Epsilon);
  356. }
  357. [Fact]
  358. public void Translate_OffsetsPosition()
  359. {
  360. var vertices = new[]
  361. {
  362. new Vector2(0, 0),
  363. new Vector2(10, 0),
  364. new Vector2(10, 10)
  365. };
  366. var polygon = new BoundingPolygon2D(vertices);
  367. var offset = new Vector2(5, 10);
  368. var translated = polygon.Translate(offset);
  369. Assert.Equal(new Vector2(5, 10), translated.Vertices[0]);
  370. Assert.Equal(new Vector2(15, 10), translated.Vertices[1]);
  371. Assert.Equal(new Vector2(15, 20), translated.Vertices[2]);
  372. }
  373. #endregion
  374. #region ContainsPoint Tests (Delegation Spot Check)
  375. [Fact]
  376. public void ContainsPoint_Inside()
  377. {
  378. var vertices = new[]
  379. {
  380. new Vector2(0, 0),
  381. new Vector2(10, 0),
  382. new Vector2(10, 10),
  383. new Vector2(0, 10)
  384. };
  385. var polygon = new BoundingPolygon2D(vertices);
  386. var point = new Vector2(5, 5);
  387. var result = polygon.Contains(point);
  388. Assert.Equal(ContainmentType.Contains, result);
  389. }
  390. [Fact]
  391. public void ContainsPoint_OnBoundary()
  392. {
  393. var vertices = new[]
  394. {
  395. new Vector2(0, 0),
  396. new Vector2(10, 0),
  397. new Vector2(10, 10),
  398. new Vector2(0, 10)
  399. };
  400. var polygon = new BoundingPolygon2D(vertices);
  401. var point = new Vector2(10, 5);
  402. var result = polygon.Contains(point);
  403. Assert.Equal(ContainmentType.Contains, result);
  404. }
  405. [Fact]
  406. public void ContainsPoint_Outside()
  407. {
  408. var vertices = new[]
  409. {
  410. new Vector2(0, 0),
  411. new Vector2(10, 0),
  412. new Vector2(10, 10),
  413. new Vector2(0, 10)
  414. };
  415. var polygon = new BoundingPolygon2D(vertices);
  416. var point = new Vector2(15, 5);
  417. var result = polygon.Contains(point);
  418. Assert.Equal(ContainmentType.Disjoint, result);
  419. }
  420. #endregion
  421. #region Deconstruct Test
  422. [Fact]
  423. public void Deconstruct()
  424. {
  425. var vertices = new[]
  426. {
  427. new Vector2(0, 0),
  428. new Vector2(10, 0),
  429. new Vector2(10, 10)
  430. };
  431. var polygon = new BoundingPolygon2D(vertices);
  432. var (v, n) = polygon;
  433. Assert.Equal(vertices, v);
  434. Assert.NotNull(n);
  435. }
  436. #endregion
  437. }
  438. }