/* //# Filename: SpatialEdge.c //# //# The SpatialEdge functions are written here //# //# Author: Peter Z. Kunszt based on A. Szalay's code //# //# Date: October 15, 1998 //# //# //# //# (c) Copyright The Johns Hopkins University 1998 //# All Rights Reserved //# //# The software and information contained herein are proprietary to The //# Johns Hopkins University, Copyright 1998. This software is furnished //# pursuant to a written license agreement and may be used, copied, //# transmitted, and stored only in accordance with the terms of such //# license and with the inclusion of the above copyright notice. This //# software and information or any other copies thereof may not be //# provided or otherwise made available to any other person. //# //# //# Modification History: //# */ #define HTM_LIB #include "SpatialEdge.h" #include //added 8/15/02 #include //added 8/15/02 /* // =========================================================================== // // Macro definitions for readability // // =========================================================================== */ #define V(x) edge->tree_->vertices_.vector_[(x)] #define IV(x) edge->tree_->nodes_.vector_[index].v_[(x)] #define IW(x) edge->tree_->nodes_.vector_[index].w_[(x)] #define LAYER edge->tree_->layers_.vector_[edge->layerindex_] /* // =========================================================================== // // Member functions for class SpatialEdge // // =========================================================================== /////////////CONSTRUCTOR////////////////////////////////// */ SpatialEdge * spatialEdgeNew(SpatialIndex * tree, size_t layerindex ) { size_t i; SpatialEdge *edge; edge = (SpatialEdge *)malloc(sizeof(SpatialEdge)); edge->tree_ = tree; edge->layerindex_ = layerindex; /* allocate space for edges and lookup table */ edge->edges_ = (Edge *)malloc(sizeof(Edge) * (LAYER.nEdge_ + 1)); edge->lTab_ = (Edge **)malloc(sizeof(Edge *) * (LAYER.nVert_ * 6)); /* initialize lookup table, we depend on that NULL */ for( i = 0; i < LAYER.nVert_ * 6; i++ ) edge->lTab_[i] = NULL; /* first vertex index for the vertices to be generated */ edge->index_ = LAYER.nVert_; return edge; } /* /////////////DESTRUCTOR/////////////////////////////////// */ void spatialEdgeDelete( SpatialEdge *edge ) { free(edge->edges_); free(edge->lTab_); } /* /////////////MAKEMIDPOINTS//////////////////////////////// // makeMidPoints: interface to this class. Set midpoints of every // node in this layer. */ void spatialEdgeMakeMidPoints( SpatialEdge *edge ) { size_t index, c=0, i; /* build up the new edges */ index = LAYER.firstIndex_; for( i=0; i < LAYER.nNode_; i++,index++){ c = spatialEdgeNewEdge(edge,c,index,0); c = spatialEdgeNewEdge(edge,c,index,1); c = spatialEdgeNewEdge(edge,c,index,2); } } /* /////////////NEWEDGE////////////////////////////////////// // newEdge: determines whether the edge em is already in the list. k // is the label of the edge within the node Returns index of next // edge, if not found, or returns same if it is already there. Also // registers the midpoint in the node. */ size_t spatialEdgeNewEdge( SpatialEdge *edge, size_t emindex, size_t index, int k) { Edge *en, *em; size_t swap; em = &(edge->edges_[emindex]); switch (k) { case 0: em->start_ = IV(1); em->end_ = IV(2); break; case 1: em->start_ = IV(0); em->end_ = IV(2); break; case 2: em->start_ = IV(0); em->end_ = IV(1); break; } /* sort the vertices by increasing index */ if(em->start_ > em->end_) { swap = em->start_; em->start_ = em->end_; em->end_ = swap; } /* check all previous edges for a match, return pointer if already present, log the midpoint with the new face as well */ if( (en=spatialEdgeEdgeMatch( edge, em )) != NULL){ IW(k) = en->mid_; return emindex; } /* this is a new edge, immediately process the midpoint, and save it with the nodes and the edge as well */ spatialEdgeInsertLookup( edge, em ); IW(k) = spatialEdgeGetMidPoint( edge, em ); em->mid_ = IW(k); return ++emindex; } /* /////////////INSERTLOOKUP///////////////////////////////// // insertLookup: insert the edge em into the lookup table. // indexed by em->start_. // Every vertex has at most 6 edges, so only // that much lookup needs to be done. */ void spatialEdgeInsertLookup( SpatialEdge *edge, Edge *em ) { int j = 6 * em->start_; int i; /* do not loop beyond 6 */ for(i=0; i<6; i++, j++) if ( edge->lTab_[j] == NULL ) { edge->lTab_[j] = em; return; } } /* /////////////EDGEMATCH//////////////////////////////////// // edgeMatch: fast lookup using the first index em->start_. // return pointer to edge if matches, null if not. */ Edge * spatialEdgeEdgeMatch( SpatialEdge *edge, Edge *em ) { int i = 6 * em->start_; while ( edge->lTab_[i] != NULL ) { if(em->end_ == edge->lTab_[i]->end_ ) return edge->lTab_[i]; i++; } return NULL; } /* /////////////GETMIDPOINT////////////////////////////////// // getMidPoint: compute the midpoint of the edge using vector // algebra and return its index in the vertex list */ size_t spatialEdgeGetMidPoint( SpatialEdge *edge, Edge * em ) { spatialVectorAddNorm( &(V(em->start_)), &(V(em->end_)), &(V(edge->index_)) ); return edge->index_++; }