Otri.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. // -----------------------------------------------------------------------
  2. // <copyright file="Otri.cs">
  3. // Original Triangle code by Jonathan Richard Shewchuk, http://www.cs.cmu.edu/~quake/triangle.html
  4. // Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
  5. // </copyright>
  6. // -----------------------------------------------------------------------
  7. namespace UnityEngine.U2D.Animation.TriangleNet
  8. .Topology
  9. {
  10. using System;
  11. using Animation.TriangleNet.Geometry;
  12. /// <summary>
  13. /// An oriented triangle.
  14. /// </summary>
  15. /// <remarks>
  16. /// Includes a pointer to a triangle and orientation. The orientation denotes an edge
  17. /// of the triangle. Hence, there are three possible orientations. By convention, each
  18. /// edge always points counterclockwise about the corresponding triangle.
  19. /// </remarks>
  20. internal struct Otri
  21. {
  22. internal Triangle tri;
  23. internal int orient; // Ranges from 0 to 2.
  24. public Triangle Triangle
  25. {
  26. get { return tri; }
  27. set { tri = value; }
  28. }
  29. public override string ToString()
  30. {
  31. if (tri == null)
  32. {
  33. return "O-TID [null]";
  34. }
  35. return String.Format("O-TID {0}", tri.hash);
  36. }
  37. #region Otri primitives (public)
  38. // For fast access
  39. static readonly int[] plus1Mod3 = { 1, 2, 0 };
  40. static readonly int[] minus1Mod3 = { 2, 0, 1 };
  41. // The following primitives are all described by Guibas and Stolfi.
  42. // However, Guibas and Stolfi use an edge-based data structure,
  43. // whereas I use a triangle-based data structure.
  44. //
  45. // lnext: finds the next edge (counterclockwise) of a triangle.
  46. //
  47. // onext: spins counterclockwise around a vertex; that is, it finds
  48. // the next edge with the same origin in the counterclockwise direction. This
  49. // edge is part of a different triangle.
  50. //
  51. // oprev: spins clockwise around a vertex; that is, it finds the
  52. // next edge with the same origin in the clockwise direction. This edge is
  53. // part of a different triangle.
  54. //
  55. // dnext: spins counterclockwise around a vertex; that is, it finds
  56. // the next edge with the same destination in the counterclockwise direction.
  57. // This edge is part of a different triangle.
  58. //
  59. // dprev: spins clockwise around a vertex; that is, it finds the
  60. // next edge with the same destination in the clockwise direction. This edge
  61. // is part of a different triangle.
  62. //
  63. // rnext: moves one edge counterclockwise about the adjacent
  64. // triangle. (It's best understood by reading Guibas and Stolfi. It
  65. // involves changing triangles twice.)
  66. //
  67. // rprev: moves one edge clockwise about the adjacent triangle.
  68. // (It's best understood by reading Guibas and Stolfi. It involves
  69. // changing triangles twice.)
  70. /// <summary>
  71. /// Find the abutting triangle; same edge. [sym(abc) -> ba*]
  72. /// </summary>
  73. /// Note that the edge direction is necessarily reversed, because the handle specified
  74. /// by an oriented triangle is directed counterclockwise around the triangle.
  75. /// </remarks>
  76. public void Sym(ref Otri ot)
  77. {
  78. ot.tri = tri.neighbors[orient].tri;
  79. ot.orient = tri.neighbors[orient].orient;
  80. }
  81. /// <summary>
  82. /// Find the abutting triangle; same edge. [sym(abc) -> ba*]
  83. /// </summary>
  84. public void Sym()
  85. {
  86. int tmp = orient;
  87. orient = tri.neighbors[tmp].orient;
  88. tri = tri.neighbors[tmp].tri;
  89. }
  90. /// <summary>
  91. /// Find the next edge (counterclockwise) of a triangle. [lnext(abc) -> bca]
  92. /// </summary>
  93. public void Lnext(ref Otri ot)
  94. {
  95. ot.tri = tri;
  96. ot.orient = plus1Mod3[orient];
  97. }
  98. /// <summary>
  99. /// Find the next edge (counterclockwise) of a triangle. [lnext(abc) -> bca]
  100. /// </summary>
  101. public void Lnext()
  102. {
  103. orient = plus1Mod3[orient];
  104. }
  105. /// <summary>
  106. /// Find the previous edge (clockwise) of a triangle. [lprev(abc) -> cab]
  107. /// </summary>
  108. public void Lprev(ref Otri ot)
  109. {
  110. ot.tri = tri;
  111. ot.orient = minus1Mod3[orient];
  112. }
  113. /// <summary>
  114. /// Find the previous edge (clockwise) of a triangle. [lprev(abc) -> cab]
  115. /// </summary>
  116. public void Lprev()
  117. {
  118. orient = minus1Mod3[orient];
  119. }
  120. /// <summary>
  121. /// Find the next edge counterclockwise with the same origin. [onext(abc) -> ac*]
  122. /// </summary>
  123. public void Onext(ref Otri ot)
  124. {
  125. //Lprev(ref ot);
  126. ot.tri = tri;
  127. ot.orient = minus1Mod3[orient];
  128. //ot.SymSelf();
  129. int tmp = ot.orient;
  130. ot.orient = ot.tri.neighbors[tmp].orient;
  131. ot.tri = ot.tri.neighbors[tmp].tri;
  132. }
  133. /// <summary>
  134. /// Find the next edge counterclockwise with the same origin. [onext(abc) -> ac*]
  135. /// </summary>
  136. public void Onext()
  137. {
  138. //LprevSelf();
  139. orient = minus1Mod3[orient];
  140. //SymSelf();
  141. int tmp = orient;
  142. orient = tri.neighbors[tmp].orient;
  143. tri = tri.neighbors[tmp].tri;
  144. }
  145. /// <summary>
  146. /// Find the next edge clockwise with the same origin. [oprev(abc) -> a*b]
  147. /// </summary>
  148. public void Oprev(ref Otri ot)
  149. {
  150. //Sym(ref ot);
  151. ot.tri = tri.neighbors[orient].tri;
  152. ot.orient = tri.neighbors[orient].orient;
  153. //ot.LnextSelf();
  154. ot.orient = plus1Mod3[ot.orient];
  155. }
  156. /// <summary>
  157. /// Find the next edge clockwise with the same origin. [oprev(abc) -> a*b]
  158. /// </summary>
  159. public void Oprev()
  160. {
  161. //SymSelf();
  162. int tmp = orient;
  163. orient = tri.neighbors[tmp].orient;
  164. tri = tri.neighbors[tmp].tri;
  165. //LnextSelf();
  166. orient = plus1Mod3[orient];
  167. }
  168. /// <summary>
  169. /// Find the next edge counterclockwise with the same destination. [dnext(abc) -> *ba]
  170. /// </summary>
  171. public void Dnext(ref Otri ot)
  172. {
  173. //Sym(ref ot);
  174. ot.tri = tri.neighbors[orient].tri;
  175. ot.orient = tri.neighbors[orient].orient;
  176. //ot.LprevSelf();
  177. ot.orient = minus1Mod3[ot.orient];
  178. }
  179. /// <summary>
  180. /// Find the next edge counterclockwise with the same destination. [dnext(abc) -> *ba]
  181. /// </summary>
  182. public void Dnext()
  183. {
  184. //SymSelf();
  185. int tmp = orient;
  186. orient = tri.neighbors[tmp].orient;
  187. tri = tri.neighbors[tmp].tri;
  188. //LprevSelf();
  189. orient = minus1Mod3[orient];
  190. }
  191. /// <summary>
  192. /// Find the next edge clockwise with the same destination. [dprev(abc) -> cb*]
  193. /// </summary>
  194. public void Dprev(ref Otri ot)
  195. {
  196. //Lnext(ref ot);
  197. ot.tri = tri;
  198. ot.orient = plus1Mod3[orient];
  199. //ot.SymSelf();
  200. int tmp = ot.orient;
  201. ot.orient = ot.tri.neighbors[tmp].orient;
  202. ot.tri = ot.tri.neighbors[tmp].tri;
  203. }
  204. /// <summary>
  205. /// Find the next edge clockwise with the same destination. [dprev(abc) -> cb*]
  206. /// </summary>
  207. public void Dprev()
  208. {
  209. //LnextSelf();
  210. orient = plus1Mod3[orient];
  211. //SymSelf();
  212. int tmp = orient;
  213. orient = tri.neighbors[tmp].orient;
  214. tri = tri.neighbors[tmp].tri;
  215. }
  216. /// <summary>
  217. /// Find the next edge (counterclockwise) of the adjacent triangle. [rnext(abc) -> *a*]
  218. /// </summary>
  219. public void Rnext(ref Otri ot)
  220. {
  221. //Sym(ref ot);
  222. ot.tri = tri.neighbors[orient].tri;
  223. ot.orient = tri.neighbors[orient].orient;
  224. //ot.LnextSelf();
  225. ot.orient = plus1Mod3[ot.orient];
  226. //ot.SymSelf();
  227. int tmp = ot.orient;
  228. ot.orient = ot.tri.neighbors[tmp].orient;
  229. ot.tri = ot.tri.neighbors[tmp].tri;
  230. }
  231. /// <summary>
  232. /// Find the next edge (counterclockwise) of the adjacent triangle. [rnext(abc) -> *a*]
  233. /// </summary>
  234. public void Rnext()
  235. {
  236. //SymSelf();
  237. int tmp = orient;
  238. orient = tri.neighbors[tmp].orient;
  239. tri = tri.neighbors[tmp].tri;
  240. //LnextSelf();
  241. orient = plus1Mod3[orient];
  242. //SymSelf();
  243. tmp = orient;
  244. orient = tri.neighbors[tmp].orient;
  245. tri = tri.neighbors[tmp].tri;
  246. }
  247. /// <summary>
  248. /// Find the previous edge (clockwise) of the adjacent triangle. [rprev(abc) -> b**]
  249. /// </summary>
  250. public void Rprev(ref Otri ot)
  251. {
  252. //Sym(ref ot);
  253. ot.tri = tri.neighbors[orient].tri;
  254. ot.orient = tri.neighbors[orient].orient;
  255. //ot.LprevSelf();
  256. ot.orient = minus1Mod3[ot.orient];
  257. //ot.SymSelf();
  258. int tmp = ot.orient;
  259. ot.orient = ot.tri.neighbors[tmp].orient;
  260. ot.tri = ot.tri.neighbors[tmp].tri;
  261. }
  262. /// <summary>
  263. /// Find the previous edge (clockwise) of the adjacent triangle. [rprev(abc) -> b**]
  264. /// </summary>
  265. public void Rprev()
  266. {
  267. //SymSelf();
  268. int tmp = orient;
  269. orient = tri.neighbors[tmp].orient;
  270. tri = tri.neighbors[tmp].tri;
  271. //LprevSelf();
  272. orient = minus1Mod3[orient];
  273. //SymSelf();
  274. tmp = orient;
  275. orient = tri.neighbors[tmp].orient;
  276. tri = tri.neighbors[tmp].tri;
  277. }
  278. /// <summary>
  279. /// Origin [org(abc) -> a]
  280. /// </summary>
  281. public Vertex Org()
  282. {
  283. return tri.vertices[plus1Mod3[orient]];
  284. }
  285. /// <summary>
  286. /// Destination [dest(abc) -> b]
  287. /// </summary>
  288. public Vertex Dest()
  289. {
  290. return tri.vertices[minus1Mod3[orient]];
  291. }
  292. /// <summary>
  293. /// Apex [apex(abc) -> c]
  294. /// </summary>
  295. public Vertex Apex()
  296. {
  297. return tri.vertices[orient];
  298. }
  299. /// <summary>
  300. /// Copy an oriented triangle.
  301. /// </summary>
  302. public void Copy(ref Otri ot)
  303. {
  304. ot.tri = tri;
  305. ot.orient = orient;
  306. }
  307. /// <summary>
  308. /// Test for equality of oriented triangles.
  309. /// </summary>
  310. public bool Equals(Otri ot)
  311. {
  312. return ((tri == ot.tri) && (orient == ot.orient));
  313. }
  314. #endregion
  315. #region Otri primitives (internal)
  316. /// <summary>
  317. /// Set Origin
  318. /// </summary>
  319. internal void SetOrg(Vertex v)
  320. {
  321. tri.vertices[plus1Mod3[orient]] = v;
  322. }
  323. /// <summary>
  324. /// Set Destination
  325. /// </summary>
  326. internal void SetDest(Vertex v)
  327. {
  328. tri.vertices[minus1Mod3[orient]] = v;
  329. }
  330. /// <summary>
  331. /// Set Apex
  332. /// </summary>
  333. internal void SetApex(Vertex v)
  334. {
  335. tri.vertices[orient] = v;
  336. }
  337. /// <summary>
  338. /// Bond two triangles together at the resepective handles. [bond(abc, bad)]
  339. /// </summary>
  340. internal void Bond(ref Otri ot)
  341. {
  342. tri.neighbors[orient].tri = ot.tri;
  343. tri.neighbors[orient].orient = ot.orient;
  344. ot.tri.neighbors[ot.orient].tri = this.tri;
  345. ot.tri.neighbors[ot.orient].orient = this.orient;
  346. }
  347. /// <summary>
  348. /// Dissolve a bond (from one side).
  349. /// </summary>
  350. /// <remarks>Note that the other triangle will still think it's connected to
  351. /// this triangle. Usually, however, the other triangle is being deleted
  352. /// entirely, or bonded to another triangle, so it doesn't matter.
  353. /// </remarks>
  354. internal void Dissolve(Triangle dummy)
  355. {
  356. tri.neighbors[orient].tri = dummy;
  357. tri.neighbors[orient].orient = 0;
  358. }
  359. /// <summary>
  360. /// Infect a triangle with the virus.
  361. /// </summary>
  362. internal void Infect()
  363. {
  364. tri.infected = true;
  365. }
  366. /// <summary>
  367. /// Cure a triangle from the virus.
  368. /// </summary>
  369. internal void Uninfect()
  370. {
  371. tri.infected = false;
  372. }
  373. /// <summary>
  374. /// Test a triangle for viral infection.
  375. /// </summary>
  376. internal bool IsInfected()
  377. {
  378. return tri.infected;
  379. }
  380. /// <summary>
  381. /// Finds a subsegment abutting a triangle.
  382. /// </summary>
  383. internal void Pivot(ref Osub os)
  384. {
  385. os = tri.subsegs[orient];
  386. }
  387. /// <summary>
  388. /// Bond a triangle to a subsegment.
  389. /// </summary>
  390. internal void SegBond(ref Osub os)
  391. {
  392. tri.subsegs[orient] = os;
  393. os.seg.triangles[os.orient] = this;
  394. }
  395. /// <summary>
  396. /// Dissolve a bond (from the triangle side).
  397. /// </summary>
  398. internal void SegDissolve(SubSegment dummy)
  399. {
  400. tri.subsegs[orient].seg = dummy;
  401. }
  402. /// <summary>
  403. /// Check a triangle's deallocation.
  404. /// </summary>
  405. internal static bool IsDead(Triangle tria)
  406. {
  407. return tria.neighbors[0].tri == null;
  408. }
  409. /// <summary>
  410. /// Set a triangle's deallocation.
  411. /// </summary>
  412. internal static void Kill(Triangle tri)
  413. {
  414. tri.neighbors[0].tri = null;
  415. tri.neighbors[2].tri = null;
  416. }
  417. #endregion
  418. }
  419. }