File indexing completed on 2024-03-24 15:17:07

0001 //#     Filename:       SpatialEdge.cpp
0002 //#
0003 //#     The SpatialEdge class is defined here.
0004 //#
0005 //#     Author:         Peter Z. Kunszt based on A. Szalay's code
0006 //#
0007 //#     Date:           October 15, 1998
0008 //#
0009 //#     SPDX-FileCopyrightText: 2000 Peter Z. Kunszt Alex S. Szalay, Aniruddha R. Thakar
0010 //#                     The Johns Hopkins University
0011 //#
0012 //#     Modification History:
0013 //#
0014 //#     Oct 18, 2001 : Dennis C. Dinge -- Replaced ValVec with std::vector
0015 //#
0016 
0017 #include "SpatialEdge.h"
0018 
0019 // ===========================================================================
0020 //
0021 // Macro definitions for readability
0022 //
0023 // ===========================================================================
0024 #define IV(x) tree_.nodes_[index].v_[(x)]
0025 #define IW(x) tree_.nodes_[index].w_[(x)]
0026 #define LAYER tree_.layers_[layerindex_]
0027 
0028 // ===========================================================================
0029 //
0030 // Member functions for class SpatialEdge
0031 //
0032 // ===========================================================================
0033 
0034 /////////////CONSTRUCTOR//////////////////////////////////
0035 //
0036 SpatialEdge::SpatialEdge(SpatialIndex &tree, size_t layerindex) : tree_(tree), layerindex_(layerindex)
0037 {
0038     edges_ = new Edge[LAYER.nEdge_ + 1];
0039     lTab_  = new Edge *[LAYER.nVert_ * 6];
0040 
0041     // initialize lookup table, we depend on that nullptr
0042     for (size_t i = 0; i < LAYER.nVert_ * 6; i++)
0043         lTab_[i] = nullptr;
0044 
0045     // first vertex index for the vertices to be generated
0046     index_ = LAYER.nVert_;
0047 }
0048 
0049 /////////////DESTRUCTOR///////////////////////////////////
0050 //
0051 SpatialEdge::~SpatialEdge()
0052 {
0053     delete[] edges_;
0054     delete[] lTab_;
0055 }
0056 
0057 /////////////MAKEMIDPOINTS////////////////////////////////
0058 // makeMidPoints: interface to this class. Set midpoints of every
0059 //                node in this layer.
0060 void SpatialEdge::makeMidPoints()
0061 {
0062     size_t c = 0;
0063     size_t index;
0064 
0065     // build up the new edges
0066 
0067     index = (size_t)LAYER.firstIndex_;
0068     for (size_t i = 0; i < LAYER.nNode_; i++, index++)
0069     {
0070         c = newEdge(c, index, 0);
0071         c = newEdge(c, index, 1);
0072         c = newEdge(c, index, 2);
0073     }
0074 }
0075 
0076 /////////////NEWEDGE//////////////////////////////////////
0077 // newEdge: determines whether the edge em is already in the list.  k
0078 //          is the label of the edge within the node Returns index of next
0079 //          edge, if not found, or returns same if it is already there.  Also
0080 //          registers the midpoint in the node.
0081 
0082 size_t SpatialEdge::newEdge(size_t emindex, size_t index, int k)
0083 {
0084     Edge *en, *em;
0085     size_t swap;
0086 
0087     em = &edges_[emindex];
0088 
0089     switch (k)
0090     {
0091         case 0:
0092             em->start_ = IV(1);
0093             em->end_   = IV(2);
0094             break;
0095         case 1:
0096             em->start_ = IV(0);
0097             em->end_   = IV(2);
0098             break;
0099         case 2:
0100             em->start_ = IV(0);
0101             em->end_   = IV(1);
0102             break;
0103     }
0104 
0105     // sort the vertices by increasing index
0106 
0107     if (em->start_ > em->end_)
0108     {
0109         swap       = em->start_;
0110         em->start_ = em->end_;
0111         em->end_   = swap;
0112     }
0113 
0114     // check all previous edges for a match, return pointer if
0115     // already present, log the midpoint with the new face as well
0116 
0117     if ((en = edgeMatch(em)) != nullptr)
0118     {
0119         IW(k) = en->mid_;
0120         return emindex;
0121     }
0122 
0123     // this is a new edge, immediately process the midpoint,
0124     // and save it with the nodes and the edge as well
0125 
0126     insertLookup(em);
0127     IW(k)    = getMidPoint(em);
0128     em->mid_ = IW(k);
0129     return ++emindex;
0130 }
0131 
0132 /////////////INSERTLOOKUP/////////////////////////////////
0133 // insertLookup: insert the edge em into the lookup table.
0134 //               indexed by em->start_.
0135 //               Every vertex has at most 6 edges, so only
0136 //               that much lookup needs to be done.
0137 void SpatialEdge::insertLookup(Edge *em)
0138 {
0139     int j = 6 * em->start_;
0140     int i;
0141 
0142     // do not loop beyond 6
0143 
0144     for (i = 0; i < 6; i++, j++)
0145     {
0146         if (lTab_[j] == nullptr)
0147         {
0148             lTab_[j] = em;
0149             return;
0150         }
0151     }
0152 }
0153 
0154 /////////////EDGEMATCH////////////////////////////////////
0155 // edgeMatch: fast lookup using the first index em->start_.
0156 //            return pointer to edge if matches, null if not.
0157 SpatialEdge::Edge *SpatialEdge::edgeMatch(Edge *em)
0158 {
0159     int i = 6 * em->start_;
0160 
0161     while (lTab_[i] != nullptr)
0162     {
0163         if (em->end_ == lTab_[i]->end_)
0164             return lTab_[i];
0165 
0166         i++;
0167     }
0168     return nullptr;
0169 }
0170 
0171 /////////////GETMIDPOINT//////////////////////////////////
0172 // getMidPoint: compute the midpoint of the edge using vector
0173 //              algebra and return its index in the vertex list
0174 size_t SpatialEdge::getMidPoint(Edge *em)
0175 {
0176     tree_.vertices_[index_] = tree_.vertices_[em->start_] + tree_.vertices_[em->end_];
0177     tree_.vertices_[index_].normalize();
0178     return index_++;
0179 }