#ifndef OctfExtensions_H #define OctfExtensions_H /* Last edited on 2009-02-09 18:26:38 by stolfi */ /* Extensions to the facet-edge data strcuture. */ #define OctfExtensions_H_copyright \ "Copyright © 1998 Universidade Estadual de Campinas (UNICAMP)" /* ELEMENT ORIENTATIONS The /canonical {d}-dimensional simplex/ {K^d} is the regular tetrahedron in {R^{d+1}} whose vertices are the unit points on each axis, {u[d,0] = (1,0,...,0), u[d,1] = (0,1,...,0), ..., u[d,d] = (0,0,...,1)}. Let $p$ be a place in either map, and $h$ be any homeomorphism from {K^3} to {p.s$} that takes the corner {u[3,i]} of {K^3} to knot {p.knt[i]} of {p.s}, for all {i} in {0..3}. The /orientation defined by {p} on {p.s$}/ is the class of homeomorphisms of {K^3} to {p.s$} that is smoothly deformable to {h}. The orientation defined by {s} on {s$} induces internal orientations for the elements of {s} . An orientation of a node is just a sign {+} or {-}. An internal orientation on an edge allows us to distinguish {+} from {-} continuous travel along it. An internal orientation of a wall {f} allows us to distinguish {+} and {-} traversal of any Jordan curve on {f}. So, for instance, the {+} travel along {e.elm[1]} is the one that traverses the link {r} of {s} with {M}-type {{0,1}} in the direction from {(s,M).knt[0]} to {(s,M).knt[1]}. Observe that the knots {(s,M).knt[i]} and {(s,M).knt[1]} are always distinct, whereas the two endpoints of {e} may be the same node of {M}. Similarly, the {+} orientation on {s.elm[2]} is that which agrees with the oriented triangle {s.knt[0],s.knt[1],s.knt[2]}. even then, {s} and {t} will imply different orientations for at least one element of that element sequence. In particular, each chip {s} defines The orientation provided by {s} on its elements makes it possible to move around {M} without ambiguity, e.g. by defining what is the `origin' of the edge {e = (s,M).elm[1]}; the `next edge' after {e} around wall [f = (s,M).elm[2]}; and so forth. */ /* ORIENTED DATA POINTERS The value of each slot {p.data[i]} is an /oriented data pointer/, which consists of a /base data pointer/ combined with /data orientation bits/. These bits depend on the internal and external orientation of the element {p.el[i]}, and which of the two maps {p} belongs to. The operations {iflip}, {oflip} and {dual} apply to oriented data pointers. They preserve the data pointer and change the orientation bits: {iflip} and {oflip} reverse the internal and external orientations, respectively, and {dual} exchanges the underlying map. The three operators satisfy the identities {iflip.oflip == oflip.iflip}, {iflip.dual == dual.oflip}, {oflip.dual == dual.iflip}, {oflip.oflip == iflip.iflip == dual.dual == nop}. Moreover, for any oriented data pointer {t}, all eight oriented pointers {t.oflip^o.iflip^i.dual^d} are distinct. The data structure enforces the identities {p.flp[0].data[1] == p.data[1].iflip} {p.flp[0].data[2] == p.data[2].iflip} {p.flp[3].data[1] == p.data[1].oflip} {p.flp[3].data[2] == p.data[2].oflip} {p.dual.data[i] == p.data[3-i].dual} */ #define OctfExtensions_H_author \ "Created by J. Stolfi, UNICAMP in jan/2007." #endif