1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
|
/**************************************************************************
* *
* Regina - A Normal Surface Theory Calculator *
* Computational Engine *
* *
* Copyright (c) 1999-2016, Ben Burton *
* For further details contact Ben Burton (bab@debian.org). *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* As an exception, when this program is distributed through (i) the *
* App Store by Apple Inc.; (ii) the Mac App Store by Apple Inc.; or *
* (iii) Google Play by Google Inc., then that store may impose any *
* digital rights management, device limits and/or redistribution *
* restrictions that are required by its terms of service. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
**************************************************************************/
/*! \file subcomplex/layeredsolidtorus.h
* \brief Deals with layered solid tori in a triangulation.
*/
#ifndef __LAYEREDSOLIDTORUS_H
#ifndef __DOXYGEN
#define __LAYEREDSOLIDTORUS_H
#endif
#include "regina-core.h"
#include "subcomplex/standardtri.h"
namespace regina {
/**
* \weakgroup subcomplex
* @{
*/
/**
* Represents a layered solid torus in a triangulation.
* A layered solid torus must contain at least one tetrahedron.
*
* Note that this class \b only represents layered solid tori with a
* (3,2,1) at their base. Thus triangulations that begin with a
* degenerate (2,1,1) mobius strip and layer over the mobius strip
* boundary (including the minimal (1,1,0) triangulation) are not
* described by this class.
*
* All optional StandardTriangulation routines are implemented for this
* class.
*/
class REGINA_API LayeredSolidTorus : public StandardTriangulation {
private:
size_t nTetrahedra;
/**< The number of tetrahedra in this torus. */
Tetrahedron<3>* base_;
/**< The tetrahedron that is glued to itself at the base of
this torus. */
int baseEdge_[6];
/**< The edges of the base tetrahedron that are identified as
a group of 1, 2 or 3 according to whether the index is
0, 1-2 or 3-5 respectively. See baseEdge() for
further details. */
int baseEdgeGroup_[6];
/**< Classifies the edges of the base tetrahedron according
to whether they are identified in a group of 1, 2 or 3. */
int baseFace_[2];
/**< The two faces of the base tetrahedron that are glued to
each other. */
Tetrahedron<3>* topLevel_;
/**< The tetrahedron on the boundary of this torus. */
int topEdge_[3][2];
/**< Returns the edges of the top tetrahedron that the meridinal
disc cuts fewest, middle or most times according to whether
the first index is 0, 1 or 2 respectively. See topEdge()
for further details. */
unsigned long meridinalCuts_[3];
/**< Returns the number of times the meridinal disc cuts each
boundary edge; this array is in non-decreasing order. */
int topEdgeGroup_[6];
/**< Classifies the edges of the boundary tetrahedron
according to whether the meridinal disc cuts them fewest,
middle or most times. */
int topFace_[2];
/**< The two faces of the boundary tetrahedron that form the
torus boundary. */
public:
/**
* Returns a newly created clone of this structure.
*
* @return a newly created clone.
*/
LayeredSolidTorus* clone() const;
/**
* Returns the number of tetrahedra in this layered solid torus.
*
* @return the number of tetrahedra.
*/
size_t size() const;
/**
* Returns the tetrahedron that is glued to itself at the base of
* this layered solid torus.
*
* @return the base tetrahedron.
*/
Tetrahedron<3>* base() const;
/**
* Returns the requested edge of the base tetrahedron belonging
* to the given group. The layering identifies the six edges
* of the base tetrahedron into a group of three, a group of two
* and a single unidentified edge; these are referred to as
* groups 3, 2 and 1 respectively.
*
* Note that <tt>baseEdgeGroup(baseEdge(group, index)) ==
* group</tt> for all values of \c group and \c index.
*
* Edges <tt>baseEdge(2,0)</tt> and <tt>baseEdge(3,0)</tt>
* will both belong to face <tt>baseFace(0)</tt>.
* Edges <tt>baseEdge(2,1)</tt> and <tt>baseEdge(3,2)</tt>
* will both belong to face <tt>baseFace(1)</tt>.
*
* @param group the group that the requested edge should belong
* to; this must be 1, 2 or 3.
* @param index the index within the given group of the requested
* edge; this must be between 0 and <i>group</i>-1 inclusive.
* Note that in group 3 the edge at index 1 is adjacent to both the
* edges at indexes 0 and 2.
* @return the edge number in the base tetrahedron of the
* requested edge; this will be between 0 and 5 inclusive.
*/
int baseEdge(int group, int index) const;
/**
* Returns the group that the given edge of the base tetrahedron
* belongs to. See baseEdge() for further details about
* groups.
*
* Note that <tt>baseEdgeGroup(baseEdge(group, index)) ==
* group</tt> for all values of \c group and \c index.
*
* @param edge the edge number in the base tetrahedron of the
* given edge; this must be between 0 and 5 inclusive.
* @return the group to which the given edge belongs; this will
* be 1, 2 or 3.
*/
int baseEdgeGroup(int edge) const;
/**
* Returns one of the two faces of the base tetrahedron that are
* glued to each other.
*
* @param index specifies which of the two faces to return; this
* must be 0 or 1.
* @return the requested face number in the base tetrahedron;
* this will be between 0 and 3 inclusive.
*/
int baseFace(int index) const;
/**
* Returns the top level tetrahedron in this layered solid torus.
* This is the tetrahedron that would be on the boundary of the
* torus if the torus were the entire manifold.
*
* @return the top level tetrahedron.
*/
Tetrahedron<3>* topLevel() const;
/**
* Returns the number of times the meridinal disc of the torus
* cuts the top level tetrahedron edges in the given group.
* See topEdge() for further details about groups.
*
* @param group the given edge group; this must be 0, 1 or 2.
* @return the number of times the meridinal disc cuts the edges
* in the given group.
*/
unsigned long meridinalCuts(int group) const;
/**
* Returns the requested edge of the top level tetrahedron belonging
* to the given group. The layering reduces five of the top
* level tetrahedron edges to three boundary edges of the solid
* torus; this divides the five initial edges into groups of size
* two, two and one.
*
* Group 0 represents the boundary edge that the meridinal disc
* cuts fewest times. Group 2 represents the boundary edge that
* the meridinal disc cuts most times. Group 1 is in the middle.
*
* Note that <tt>topEdgeGroup(topEdge(group, index)) ==
* group</tt> for all values of \c group and \c index that
* actually correspond to an edge.
*
* Edges <tt>topEdge(group, 0)</tt> will all belong to face
* <tt>topFace(0)</tt>. Edges <tt>topEdge(group, 1)</tt>
* (if they exist) will all belong to face <tt>topFace(1)</tt>.
*
* @param group the group that the requested edge should belong
* to; this must be 0, 1 or 2.
* @param index the index within the given group of the requested
* edge; this must be 0 or 1. Note that one of the groups only
* contains one tetrahedron edge, in which case this edge will be
* stored at index 0.
* @return the edge number in the top level tetrahedron of the
* requested edge (between 0 and 5 inclusive), or -1 if there is
* no such edge (only possible if the given group was the group
* of size one and the given index was 1).
*/
int topEdge(int group, int index) const;
/**
* Returns the group that the given edge of the top level
* tetrahedron belongs to. See topEdge() for further details
* about groups.
*
* Note that <tt>topEdgeGroup(topEdge(group, index)) ==
* group</tt> for all values of \c group and \c index that
* actually correspond to an edge.
*
* @param edge the edge number in the top level tetrahedron of
* the given edge; this must be between 0 and 5 inclusive.
* @return the group to which the given edge belongs (0, 1 or 2),
* or -1 if this edge does not belong to any group (only possible
* if this is the unique edge in the top tetrahedron not on the
* torus boundary).
*/
int topEdgeGroup(int edge) const;
/**
* Returns one of the two faces of the top level tetrahedron that
* form the boundary of this layered solid torus.
*
* @param index specifies which of the two faces to return; this
* must be 0 or 1.
* @return the requested face number in the top level tetrahedron;
* this will be between 0 and 3 inclusive.
*/
int topFace(int index) const;
/**
* Flattens this layered solid torus to a Mobius band.
* A newly created modified triangulation is returned; the
* original triangulation is unchanged.
*
* Note that there are three different ways in which this layered
* solid torus can be flattened, corresponding to the three
* different edges of the boundary torus that could become the
* boundary edge of the new Mobius band.
*
* @param original the triangulation containing this layered
* solid torus; this triangulation will not be changed.
* @param mobiusBandBdry the edge group on the boundary of this
* layered solid torus that will become the boundary of the new
* Mobius band (the remaining edge groups will become internal
* edges of the new Mobius band). This must be 0, 1 or 2.
* See topEdge() for further details about edge groups.
* @return a newly created triangulation in which this layered
* solid torus has been flattened to a Mobius band.
*/
Triangulation<3>* flatten(const Triangulation<3>* original,
int mobiusBandBdry) const;
/**
* Adjusts the details of this layered solid torus according to
* the given isomorphism between triangulations.
*
* The given isomorphism must describe a mapping from \a originalTri
* to \a newTri, and this layered solid torus must currently
* refer to tetrahedra in \a originalTri. After this routine is
* called this structure will instead refer to the corresponding
* tetrahedra in \a newTri (with changes in vertex/face
* numbering also accounted for).
*
* \pre This layered solid torus currently refers to tetrahedra
* in \a originalTri, and \a iso describes a mapping from
* \a originalTri to \a newTri.
*
* @param originalTri the triangulation currently referenced by this
* layered solid torus.
* @param iso the mapping from \a originalTri to \a newTri.
* @param newTri the triangulation to be referenced by the updated
* layered solid torus.
*/
void transform(const Triangulation<3>* originalTri,
const Isomorphism<3>* iso, Triangulation<3>* newTri);
/**
* Determines if the given tetrahedron forms the base of a
* layered solid torus within a triangulation. The torus need
* not be the entire triangulation; the top level tetrahedron of
* the torus may be glued to something else (or to itself).
*
* Note that the base tetrahedron of a layered solid torus is the
* tetrahedron furthest from the boundary of the torus, i.e. the
* tetrahedron glued to itself with a twist.
*
* @param tet the tetrahedron to examine as a potential base.
* @return a newly created structure containing details of the
* layered solid torus, or \c null if the given tetrahedron is
* not the base of a layered solid torus.
*/
static LayeredSolidTorus* formsLayeredSolidTorusBase(
Tetrahedron<3>* tet);
/**
* Determines if the given tetrahedron forms the top level
* tetrahedron of a layered solid torus, with the two given
* faces of this tetrahedron representing the boundary of the
* layered solid torus.
*
* Note that the two given faces need not be boundary triangles in the
* overall triangulation. That is, the layered solid torus may be
* a subcomplex of some larger triangulation. For example, the
* two given faces may be joined to some other tetrahedra outside
* the layered solid torus or they may be joined to each other.
* In fact, they may even extend this smaller layered solid torus
* to a larger layered solid torus.
*
* @param tet the tetrahedron to examine as a potential top
* level of a layered solid torus.
* @param topFace1 the face number of the given tetrahedron that
* should represent the first boundary triangle of the layered solid
* torus. This should be between 0 and 3 inclusive.
* @param topFace2 the face number of the given tetrahedron that
* should represent the second boundary triangle of the layered solid
* torus. This should be between 0 and 3 inclusive, and should
* not be equal to \a topFace1.
* @return a newly created structure containing details of the
* layered solid torus, or \c null if the given tetrahedron with
* its two faces do not form the top level of a layered solid torus.
*/
static LayeredSolidTorus* formsLayeredSolidTorusTop(
Tetrahedron<3>* tet, unsigned topFace1, unsigned topFace2);
/**
* Determines if the given triangulation component forms a
* layered solid torus in its entirity.
*
* Note that, unlike formsLayeredSolidTorusBase(), this routine
* tests for a component that is a layered solid torus with no
* additional tetrahedra or gluings. That is, the two boundary
* triangles of the layered solid torus must in fact be boundary
* triangles of the component.
*
* @param comp the triangulation component to examine.
* @return a newly created structure containing details of the
* layered solid torus, or \c null if the given component is not
* a layered solid torus.
*/
static LayeredSolidTorus* isLayeredSolidTorus(Component<3>* comp);
Manifold* manifold() const;
AbelianGroup* homology() const;
std::ostream& writeName(std::ostream& out) const;
std::ostream& writeTeXName(std::ostream& out) const;
void writeTextLong(std::ostream& out) const;
private:
/**
* Create a new uninitialised structure.
*/
LayeredSolidTorus();
/**
* Fills <tt>topEdge[destGroup]</tt> with the edges produced by
* following the edges in group \c sourceGroup from the current
* top level tetrahedron up to the next layered tetrahedron.
*
* Note that which edge is placed in <tt>topEdge[][0]</tt> and
* which edge is placed in <tt>topEdge[][1]</tt> will be an
* arbitrary decision; these may need to be switched later on.
*
* \pre There is a next layered tetrahedron.
* \pre Member variables \a topLevel and \a topFace have not yet been
* changed to reflect the next layered tetrahedron.
* \pre The edges in group \a destGroup in the next layered
* tetrahedron are actually layered onto the edges in group \a
* sourceGroup in the current top level tetrahedron.
*
* @param sourceGroup the group in the current top level
* tetrahedron to which the edges belong.
* @param destGroup the group in the next layered tetrahedron to
* which the same edges belong.
*/
void followEdge(int destGroup, int sourceGroup);
};
/**
* Deprecated typedef for backward compatibility. This typedef will
* be removed in a future release of Regina.
*
* \deprecated The class NLayeredSolidTorus has now been renamed to
* LayeredSolidTorus.
*/
REGINA_DEPRECATED typedef LayeredSolidTorus NLayeredSolidTorus;
/*@}*/
// Inline functions for LayeredSolidTorus
inline LayeredSolidTorus::LayeredSolidTorus() {
}
inline size_t LayeredSolidTorus::size() const {
return nTetrahedra;
}
inline Tetrahedron<3>* LayeredSolidTorus::base() const {
return base_;
}
inline int LayeredSolidTorus::baseEdge(int group, int index) const {
return group == 1 ? baseEdge_[index] :
group == 2 ? baseEdge_[1 + index] : baseEdge_[3 + index];
}
inline int LayeredSolidTorus::baseEdgeGroup(int edge) const {
return baseEdgeGroup_[edge];
}
inline int LayeredSolidTorus::baseFace(int index) const {
return baseFace_[index];
}
inline Tetrahedron<3>* LayeredSolidTorus::topLevel() const {
return topLevel_;
}
inline unsigned long LayeredSolidTorus::meridinalCuts(int group) const {
return meridinalCuts_[group];
}
inline int LayeredSolidTorus::topEdge(int group, int index) const {
return topEdge_[group][index];
}
inline int LayeredSolidTorus::topEdgeGroup(int edge) const {
return topEdgeGroup_[edge];
}
inline int LayeredSolidTorus::topFace(int index) const {
return topFace_[index];
}
inline std::ostream& LayeredSolidTorus::writeName(std::ostream& out) const {
return out << "LST(" << meridinalCuts_[0] << ',' << meridinalCuts_[1] << ','
<< meridinalCuts_[2] << ')';
}
inline std::ostream& LayeredSolidTorus::writeTeXName(std::ostream& out) const {
return out << "\\mathop{\\rm LST}(" << meridinalCuts_[0] << ','
<< meridinalCuts_[1] << ',' << meridinalCuts_[2] << ')';
}
inline void LayeredSolidTorus::writeTextLong(std::ostream& out) const {
out << "( " << meridinalCuts_[0] << ", " << meridinalCuts_[1] << ", "
<< meridinalCuts_[2] << " ) layered solid torus";
}
} // namespace regina
#endif
|