123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- // -----------------------------------------------------------------------
- // <copyright file="Otri.cs">
- // Original Triangle code by Jonathan Richard Shewchuk, http://www.cs.cmu.edu/~quake/triangle.html
- // Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
- // </copyright>
- // -----------------------------------------------------------------------
- namespace UnityEngine.U2D.Animation.TriangleNet
- .Topology
- {
- using System;
- using Animation.TriangleNet.Geometry;
- /// <summary>
- /// An oriented triangle.
- /// </summary>
- /// <remarks>
- /// Includes a pointer to a triangle and orientation. The orientation denotes an edge
- /// of the triangle. Hence, there are three possible orientations. By convention, each
- /// edge always points counterclockwise about the corresponding triangle.
- /// </remarks>
- internal struct Otri
- {
- internal Triangle tri;
- internal int orient; // Ranges from 0 to 2.
- public Triangle Triangle
- {
- get { return tri; }
- set { tri = value; }
- }
- public override string ToString()
- {
- if (tri == null)
- {
- return "O-TID [null]";
- }
- return String.Format("O-TID {0}", tri.hash);
- }
- #region Otri primitives (public)
- // For fast access
- static readonly int[] plus1Mod3 = { 1, 2, 0 };
- static readonly int[] minus1Mod3 = { 2, 0, 1 };
- // The following primitives are all described by Guibas and Stolfi.
- // However, Guibas and Stolfi use an edge-based data structure,
- // whereas I use a triangle-based data structure.
- //
- // lnext: finds the next edge (counterclockwise) of a triangle.
- //
- // onext: spins counterclockwise around a vertex; that is, it finds
- // the next edge with the same origin in the counterclockwise direction. This
- // edge is part of a different triangle.
- //
- // oprev: spins clockwise around a vertex; that is, it finds the
- // next edge with the same origin in the clockwise direction. This edge is
- // part of a different triangle.
- //
- // dnext: spins counterclockwise around a vertex; that is, it finds
- // the next edge with the same destination in the counterclockwise direction.
- // This edge is part of a different triangle.
- //
- // dprev: spins clockwise around a vertex; that is, it finds the
- // next edge with the same destination in the clockwise direction. This edge
- // is part of a different triangle.
- //
- // rnext: moves one edge counterclockwise about the adjacent
- // triangle. (It's best understood by reading Guibas and Stolfi. It
- // involves changing triangles twice.)
- //
- // rprev: moves one edge clockwise about the adjacent triangle.
- // (It's best understood by reading Guibas and Stolfi. It involves
- // changing triangles twice.)
- /// <summary>
- /// Find the abutting triangle; same edge. [sym(abc) -> ba*]
- /// </summary>
- /// Note that the edge direction is necessarily reversed, because the handle specified
- /// by an oriented triangle is directed counterclockwise around the triangle.
- /// </remarks>
- public void Sym(ref Otri ot)
- {
- ot.tri = tri.neighbors[orient].tri;
- ot.orient = tri.neighbors[orient].orient;
- }
- /// <summary>
- /// Find the abutting triangle; same edge. [sym(abc) -> ba*]
- /// </summary>
- public void Sym()
- {
- int tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Find the next edge (counterclockwise) of a triangle. [lnext(abc) -> bca]
- /// </summary>
- public void Lnext(ref Otri ot)
- {
- ot.tri = tri;
- ot.orient = plus1Mod3[orient];
- }
- /// <summary>
- /// Find the next edge (counterclockwise) of a triangle. [lnext(abc) -> bca]
- /// </summary>
- public void Lnext()
- {
- orient = plus1Mod3[orient];
- }
- /// <summary>
- /// Find the previous edge (clockwise) of a triangle. [lprev(abc) -> cab]
- /// </summary>
- public void Lprev(ref Otri ot)
- {
- ot.tri = tri;
- ot.orient = minus1Mod3[orient];
- }
- /// <summary>
- /// Find the previous edge (clockwise) of a triangle. [lprev(abc) -> cab]
- /// </summary>
- public void Lprev()
- {
- orient = minus1Mod3[orient];
- }
- /// <summary>
- /// Find the next edge counterclockwise with the same origin. [onext(abc) -> ac*]
- /// </summary>
- public void Onext(ref Otri ot)
- {
- //Lprev(ref ot);
- ot.tri = tri;
- ot.orient = minus1Mod3[orient];
- //ot.SymSelf();
- int tmp = ot.orient;
- ot.orient = ot.tri.neighbors[tmp].orient;
- ot.tri = ot.tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Find the next edge counterclockwise with the same origin. [onext(abc) -> ac*]
- /// </summary>
- public void Onext()
- {
- //LprevSelf();
- orient = minus1Mod3[orient];
- //SymSelf();
- int tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Find the next edge clockwise with the same origin. [oprev(abc) -> a*b]
- /// </summary>
- public void Oprev(ref Otri ot)
- {
- //Sym(ref ot);
- ot.tri = tri.neighbors[orient].tri;
- ot.orient = tri.neighbors[orient].orient;
- //ot.LnextSelf();
- ot.orient = plus1Mod3[ot.orient];
- }
- /// <summary>
- /// Find the next edge clockwise with the same origin. [oprev(abc) -> a*b]
- /// </summary>
- public void Oprev()
- {
- //SymSelf();
- int tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- //LnextSelf();
- orient = plus1Mod3[orient];
- }
- /// <summary>
- /// Find the next edge counterclockwise with the same destination. [dnext(abc) -> *ba]
- /// </summary>
- public void Dnext(ref Otri ot)
- {
- //Sym(ref ot);
- ot.tri = tri.neighbors[orient].tri;
- ot.orient = tri.neighbors[orient].orient;
- //ot.LprevSelf();
- ot.orient = minus1Mod3[ot.orient];
- }
- /// <summary>
- /// Find the next edge counterclockwise with the same destination. [dnext(abc) -> *ba]
- /// </summary>
- public void Dnext()
- {
- //SymSelf();
- int tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- //LprevSelf();
- orient = minus1Mod3[orient];
- }
- /// <summary>
- /// Find the next edge clockwise with the same destination. [dprev(abc) -> cb*]
- /// </summary>
- public void Dprev(ref Otri ot)
- {
- //Lnext(ref ot);
- ot.tri = tri;
- ot.orient = plus1Mod3[orient];
- //ot.SymSelf();
- int tmp = ot.orient;
- ot.orient = ot.tri.neighbors[tmp].orient;
- ot.tri = ot.tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Find the next edge clockwise with the same destination. [dprev(abc) -> cb*]
- /// </summary>
- public void Dprev()
- {
- //LnextSelf();
- orient = plus1Mod3[orient];
- //SymSelf();
- int tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Find the next edge (counterclockwise) of the adjacent triangle. [rnext(abc) -> *a*]
- /// </summary>
- public void Rnext(ref Otri ot)
- {
- //Sym(ref ot);
- ot.tri = tri.neighbors[orient].tri;
- ot.orient = tri.neighbors[orient].orient;
- //ot.LnextSelf();
- ot.orient = plus1Mod3[ot.orient];
- //ot.SymSelf();
- int tmp = ot.orient;
- ot.orient = ot.tri.neighbors[tmp].orient;
- ot.tri = ot.tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Find the next edge (counterclockwise) of the adjacent triangle. [rnext(abc) -> *a*]
- /// </summary>
- public void Rnext()
- {
- //SymSelf();
- int tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- //LnextSelf();
- orient = plus1Mod3[orient];
- //SymSelf();
- tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Find the previous edge (clockwise) of the adjacent triangle. [rprev(abc) -> b**]
- /// </summary>
- public void Rprev(ref Otri ot)
- {
- //Sym(ref ot);
- ot.tri = tri.neighbors[orient].tri;
- ot.orient = tri.neighbors[orient].orient;
- //ot.LprevSelf();
- ot.orient = minus1Mod3[ot.orient];
- //ot.SymSelf();
- int tmp = ot.orient;
- ot.orient = ot.tri.neighbors[tmp].orient;
- ot.tri = ot.tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Find the previous edge (clockwise) of the adjacent triangle. [rprev(abc) -> b**]
- /// </summary>
- public void Rprev()
- {
- //SymSelf();
- int tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- //LprevSelf();
- orient = minus1Mod3[orient];
- //SymSelf();
- tmp = orient;
- orient = tri.neighbors[tmp].orient;
- tri = tri.neighbors[tmp].tri;
- }
- /// <summary>
- /// Origin [org(abc) -> a]
- /// </summary>
- public Vertex Org()
- {
- return tri.vertices[plus1Mod3[orient]];
- }
- /// <summary>
- /// Destination [dest(abc) -> b]
- /// </summary>
- public Vertex Dest()
- {
- return tri.vertices[minus1Mod3[orient]];
- }
- /// <summary>
- /// Apex [apex(abc) -> c]
- /// </summary>
- public Vertex Apex()
- {
- return tri.vertices[orient];
- }
- /// <summary>
- /// Copy an oriented triangle.
- /// </summary>
- public void Copy(ref Otri ot)
- {
- ot.tri = tri;
- ot.orient = orient;
- }
- /// <summary>
- /// Test for equality of oriented triangles.
- /// </summary>
- public bool Equals(Otri ot)
- {
- return ((tri == ot.tri) && (orient == ot.orient));
- }
- #endregion
- #region Otri primitives (internal)
- /// <summary>
- /// Set Origin
- /// </summary>
- internal void SetOrg(Vertex v)
- {
- tri.vertices[plus1Mod3[orient]] = v;
- }
- /// <summary>
- /// Set Destination
- /// </summary>
- internal void SetDest(Vertex v)
- {
- tri.vertices[minus1Mod3[orient]] = v;
- }
- /// <summary>
- /// Set Apex
- /// </summary>
- internal void SetApex(Vertex v)
- {
- tri.vertices[orient] = v;
- }
- /// <summary>
- /// Bond two triangles together at the resepective handles. [bond(abc, bad)]
- /// </summary>
- internal void Bond(ref Otri ot)
- {
- tri.neighbors[orient].tri = ot.tri;
- tri.neighbors[orient].orient = ot.orient;
- ot.tri.neighbors[ot.orient].tri = this.tri;
- ot.tri.neighbors[ot.orient].orient = this.orient;
- }
- /// <summary>
- /// Dissolve a bond (from one side).
- /// </summary>
- /// <remarks>Note that the other triangle will still think it's connected to
- /// this triangle. Usually, however, the other triangle is being deleted
- /// entirely, or bonded to another triangle, so it doesn't matter.
- /// </remarks>
- internal void Dissolve(Triangle dummy)
- {
- tri.neighbors[orient].tri = dummy;
- tri.neighbors[orient].orient = 0;
- }
- /// <summary>
- /// Infect a triangle with the virus.
- /// </summary>
- internal void Infect()
- {
- tri.infected = true;
- }
- /// <summary>
- /// Cure a triangle from the virus.
- /// </summary>
- internal void Uninfect()
- {
- tri.infected = false;
- }
- /// <summary>
- /// Test a triangle for viral infection.
- /// </summary>
- internal bool IsInfected()
- {
- return tri.infected;
- }
- /// <summary>
- /// Finds a subsegment abutting a triangle.
- /// </summary>
- internal void Pivot(ref Osub os)
- {
- os = tri.subsegs[orient];
- }
- /// <summary>
- /// Bond a triangle to a subsegment.
- /// </summary>
- internal void SegBond(ref Osub os)
- {
- tri.subsegs[orient] = os;
- os.seg.triangles[os.orient] = this;
- }
- /// <summary>
- /// Dissolve a bond (from the triangle side).
- /// </summary>
- internal void SegDissolve(SubSegment dummy)
- {
- tri.subsegs[orient].seg = dummy;
- }
- /// <summary>
- /// Check a triangle's deallocation.
- /// </summary>
- internal static bool IsDead(Triangle tria)
- {
- return tria.neighbors[0].tri == null;
- }
- /// <summary>
- /// Set a triangle's deallocation.
- /// </summary>
- internal static void Kill(Triangle tri)
- {
- tri.neighbors[0].tri = null;
- tri.neighbors[2].tri = null;
- }
- #endregion
- }
- }
|