/* see Lines.h for documentation \tableofcontents */ #include "RegionInterpolator.h" using namespace std; namespace RegionInterpol { /* 1 Constructors and Destructor */ Match :: Match (RegionForInterpolation *src, RegionForInterpolation *trgt, string nam,string dscrpton) { description = dscrpton; name = nam; source = src; target = trgt; vector > tmp; tmp.resize (source->getNrOfFaces() + target->getNrOfFaces()); for(int i = 0; igetNrOfFaces(); i++) { vector tmpline = source->getFace(i)->getCycle()->getOutLine();; tmp[i].resize(tmpline.size()); for(unsigned int j = 0; j < tmpline.size(); j++) { tmp[i][j] = new LineWA(&tmpline[j]); } } for(int i = 0; i < target->getNrOfFaces(); i++) { vector tmpline = target->getFace(i)->getCycle()->getOutLine();; tmp[i + source->getNrOfFaces()].resize(tmpline.size()); for(unsigned int j = 0; j < tmpline.size(); j++) { tmp[i + source->getNrOfFaces()][j] = new LineWA(&tmpline[j]); } } greatestDist = Utils::getMaxDistance(tmp); LineWA* del; for(vector >::iterator it1= tmp.begin(); it1!= tmp.end(); ++it1) { for(vector::iterator it2= (*it1).begin(); it2 != (*it1).end(); ++it2) { del= (*it2); delete del; } } } /* 1 Get functions 1.1 getName() */ string Match :: getName() { return(name); } /* 1.1 getDescription() */ string Match :: getDescription() { return(description); } /* 1.1 getAreaRating() */ double Match :: getAreaRating() { return(Arearating); } /* 1.1 getOverlapRating() */ double Match :: getOverlapRating() { return(Ovelaprating); } /* 1.1 getHausdorffRating() */ double Match :: getHausdorffRating() { return(Hausdorffrating); } /* 1.1 getLinarRating() */ double Match :: getLinarRating() { return(linearRating); } /* 1.1 getRating() */ double Match::getRating(double AreaWeight, double OverlapWeigth, double HausdorffWeight, double LinearWeigth) { return(Arearating * AreaWeight + Ovelaprating * OverlapWeigth + linearRating * LinearWeigth + Hausdorffrating * HausdorffWeight); } /* 1.1 getSource() */ RegionForInterpolation *Match :: getSource() { return(source); } /* 1.1 getTarget() */ RegionForInterpolation *Match :: getTarget() { return(target); } void Match::setSource(RegionForInterpolation *arg) { source= arg; } void Match::setTarget(RegionForInterpolation *arg) { target= arg; } void Match::nullify() { source=0; target=0; for(map::iterator it= maps.begin(); it!= maps.end(); ++it) (*it).second=0; } /* 1.1 getMatches() */ vector Match :: getMatches(RegionTreeNode *source) { int sourceHash = findIndex(source); vector res; if(maps.find(sourceHash) == maps.end()) { return(res); } SingleMatch* tmp = maps[sourceHash]; tmp->removeNulls(); for(int i = 0; i < tmp->getNrTargets(); i++) { res.push_back(tmp->getTargetAt(i)); } return(res); } /* 1.1 getMaps() */ map Match :: getMaps() { return(maps); } /* 1.1 getTargetChildren() */ vector Match :: getTargetChildren(RegionTreeNode *source) { vector tmp = getMatches(source); vector res; for(unsigned int i = 0; i < tmp.size(); i++) { if(dynamic_cast (tmp[i])) { Face* tmpFace = (Face*) tmp[i]; vector tmpCHTN = tmpFace->getCycle()->getChildren(); for(unsigned int j = 0; j < tmpCHTN.size(); j++) { res.push_back(tmpCHTN.at(j)); } for(int j = 0; j < tmpFace->getNrOfHoles(); j++) { res.push_back(tmpFace->getHole(j)); } } if(dynamic_cast (tmp[i])) { ConvexHullTreeNode* tmpCHTN = (ConvexHullTreeNode*)tmp[i]; vector tmpChildren = tmpCHTN->getChildren(); for(unsigned int j = 0 ; j< tmpChildren.size(); j++) { res.push_back(tmpChildren.at(j)); } } } return(res); } /* 1 Set functions 1.1 addMatch() */ void Match :: addMatch(RegionTreeNode *source, RegionTreeNode *target) { int sourceHash = findIndex(source); #ifdef DEMATCH cout<< "addMatch: "<< source->hashCode()<< " " << target->hashCode()<< endl; #endif if(maps.find(sourceHash) == maps.end()) { SingleMatch *tmp = new SingleMatch(source,target); maps.insert(map :: value_type(sourceHash, tmp)); } else { if(maps[sourceHash]->getSource()->equals(source)) { maps[sourceHash]->addTarget(target); } else { #ifdef DEMATCH cout << "echtes Problem" << endl; #endif } } } /* 1.1 addName() */ void Match :: addName(string newName) { name += '\n' + newName; } /* 1.1 removeMatches() */ void Match :: removeMatches(RegionTreeNode *toDelete) { if(toDelete != NULL) { removeSingleMatch(toDelete); if(dynamic_cast (toDelete)) { vector children = ((ConvexHullTreeNode*) toDelete)->getChildren(); for(unsigned int i = 0; i < children.size(); i++) { removeMatches(children.at(i)); } } if(dynamic_cast (toDelete)) { Face* deleteFace=( (Face*) toDelete); removeMatches(deleteFace->getCycle()); for(int i = 0; igetNrOfHoles(); i++) { removeMatches(deleteFace->getHole(i)); } } if(dynamic_cast (toDelete)) { RegionForInterpolation* deleteRegion = ((RegionForInterpolation*) toDelete); for(int i = 0; i < deleteRegion->getNrOfFaces(); i++) { removeMatches(deleteRegion->getFace(i)); } } } } /* 1 Public Methods 1.1 finalize() */ void Match :: finalize() { map :: iterator iter = maps.begin(); while(iter != maps.end()) { SingleMatch *tmp = (*iter).second; tmp->removeNulls(); iter++; if(tmp->getNrTargets() == 1 && dynamic_cast (tmp->getTargetAt(0))) //1 to 1 Match of ConvexHullTrees search and delete huge rotatings { ConvexHullTreeNode *stmp = (ConvexHullTreeNode*) tmp->getSource(); ConvexHullTreeNode *ttmp=(ConvexHullTreeNode*) tmp->getTargetAt(0); if( (dynamic_cast (stmp->getParentNode())) && (dynamic_cast (ttmp->getParentNode())) ) { ConvexHullTreeNode *parentS = ((ConvexHullTreeNode*) stmp->getParentNode()); ConvexHullTreeNode *parentT = ((ConvexHullTreeNode*) ttmp->getParentNode()); vector linesS = parentS->getLineForChild(stmp); vector linesT = parentT->getLineForChild(ttmp); if(linesS.size() == 2 && linesT.size() == 2) { vector *linesNeiS = new vector (4); vector *linesNeiT = new vector (4); linesNeiS->at(1) = linesS[0]; linesNeiS->at(2) = linesS[1]; linesNeiT->at(1) = linesT[0]; linesNeiT->at(2) = linesT[1]; vector parentSLL = parentS->getOutLine(); vector parentTLL = parentT->getOutLine(); for(unsigned int i = 0; i < parentSLL.size(); i++) { #ifdef DEMATCH cout << parentSLL[i] << " vs. " << *linesS[0] << endl; cout << parentSLL[(i + 1) % parentSLL.size()] << " vs. " << linesS[1] << endl; #endif if(parentSLL[i].equals(linesS[0]) && parentSLL[(i+1)%parentSLL.size()].equals(linesS[1])) { linesNeiS->at(0) = parentSLL[(i-1+parentSLL.size())% parentSLL.size()]; linesNeiS->at(3)=parentSLL[(i+2)%parentSLL.size()]; } } for(unsigned int i = 0; i < parentTLL.size(); i++) { if(parentTLL[i].equals(linesT[0]) && parentTLL[ (i+1) % parentTLL.size()] .equals(linesT[1])) { linesNeiT->at(0)=parentTLL[(i-1+parentTLL.size()) % parentTLL.size()]; linesNeiT->at(3)=parentTLL[(i+2)%parentTLL.size()]; } } Utils :: computeLineAngles(linesNeiS); Utils :: computeLineAngles(linesNeiT); double angleT = linesNeiT->at(1).getAngle(); double angleS = linesNeiS->at(1).getAngle(); if(linesNeiS->at(0).getAngle()>linesNeiS->at(1).getAngle()) { linesNeiS->at(1).setAngle (linesNeiS->at(1).getAngle() + 2 * M_PI); } if(linesNeiS->at(1).getAngle()>linesNeiS->at(2).getAngle()) { linesNeiS->at(2).setAngle (linesNeiS->at(2).getAngle() + 2 * M_PI); } if(linesNeiT->at(0).getAngle()>linesNeiT->at(1).getAngle()) { linesNeiT->at(1).setAngle (linesNeiT->at(1).getAngle() + 2 * M_PI); } if(linesNeiT->at(1).getAngle()>linesNeiT->at(2).getAngle()) { linesNeiT->at(2).setAngle (linesNeiT->at(2).getAngle() + 2 * M_PI); } if( (angleSat(0).getAngle() || angleS > linesNeiT->at(2).getAngle() ) && (angleS + 2 * M_PI < linesNeiT->at(0).getAngle() || angleS + 2 * M_PI > linesNeiT->at(2).getAngle() ) ) { tmp->removeTargets(); } if( (angleT < linesNeiS->at(0).getAngle() || angleT > linesNeiS->at(2).getAngle() ) && (angleT + 2 * M_PI < linesNeiS->at(0).getAngle() || angleT + 2 * M_PI > linesNeiS->at(2).getAngle() ) ) { tmp->removeTargets(); } } } } if(tmp!=NULL&&tmp->getNrTargets()>1) //1 to N Match { if(dynamic_cast(tmp->getSource())) //1 to N Match of Faces try to split them { Face *sou = (Face*) tmp->getSource(); Face *t1 = (Face*) tmp->getTargetAt(0); Face *t2 = (Face*) tmp->getTargetAt(1); RegionForInterpolation *parentsou = sou->getParent(); removeMatches(sou); removeMatches(t1); removeMatches(t2); vector *newSources = parentsou->splitOnLine(sou-> getCycle()->getSplitLine(t1->getCycle() , t2->getCycle())); if( newSources->size() == 2 && newSources->at(0) != NULL && newSources->at(1) != NULL) { vector *oldtargets = new vector (2); oldtargets->at(0) = t1; oldtargets->at(1) = t2; vector new1; vector new2; vector old1; vector old2; new1.push_back(newSources->at(0)); new2.push_back(newSources->at(1)); old1.push_back(getBestMatch(newSources->at(0), oldtargets)); old2.push_back(getBestMatch(newSources->at(1), oldtargets)); matchFaces(&new1, &old1); matchFaces(&new2, &old2); for(int i = 2; i< tmp->getNrTargets(); i++) { vector tmpTar; tmpTar.push_back(( (Face*) tmp->getTargetAt(i))); vector tmpSour; tmpSour.push_back(getBestMatch(tmpTar[0], newSources)); matchFaces(&tmpSour, &tmpTar); } } else //Split failed match each face with best matched { vector tmpSour; tmpSour.push_back(sou); vector tmpTar; vector tmpTar2; for(int i = 0; i < tmp->getNrTargets(); i++) { tmpTar.push_back( (Face*) tmp->getTargetAt(i)); } tmpTar2.push_back(getBestMatch(sou, &tmpTar)); matchFaces(&tmpSour, &tmpTar2); } iter =maps.begin(); continue; } if(dynamic_cast(tmp->getSource())) { vector tmpSour; tmpSour.push_back( (ConvexHullTreeNode*) tmp->getSource()); removeMatches((ConvexHullTreeNode*) tmp->getSource()); vector tmpTar; vector tmpTar2; for(int i = 0; i < tmp->getNrTargets(); i++) { tmpTar.push_back( (ConvexHullTreeNode*) tmp->getTargetAt(i)); } tmpTar2.push_back(getBestMatch( (ConvexHullTreeNode*) tmp->getSource(), &tmpTar)); matchCHTNs(tmpSour, tmpTar2); iter = maps.begin(); continue; } } } } /* 1 Operators 1.1 $<<$ */ ostream& operator << (ostream& s, Match *match) { s << match->getName() << endl << match->getDescription() << " Ratings: " <getAreaRating() << " OR: " << match->getOverlapRating() << " HR: " << match->getHausdorffRating() << " LR: " << match->getLinarRating() << endl; #ifdef DEMATCH map :: iterator iter = match->maps.begin(); while(iter != match->maps.end()) { s << "Key" << (*iter).first; s << (*(*iter).second); iter++; } #endif return s; } /* 1 Protected Methods 1.1 generateRatings() */ void Match :: generateRatings() { #ifdef DEMATCH cout<<"gr"<getNrOfFaces(); i++) { vector tmp = getMatches(source->getFace(i)); #ifdef DEMATCH cout << tmp.size() << endl; #endif if(tmp.size() == 0) { Hausdorffrating += Utils::getDiameter(Utils :: convertCHLine2LineWA (source->getFace(i)->getCycle()->getLines())); Ovelaprating += 0.0; Arearating += 0.0; linearRating += 0.5; NrOfRatings++; } else { rateFace(source->getFace(i), tmp); } } for(int i = 0; igetNrOfFaces(); i++) { vector tmp = getMatches(target->getFace(i)); #ifdef DEMATCH cout<getFace(i)->getCycle()->getLines())); Ovelaprating += 0.0; Arearating += 0.0; linearRating += 0.5; NrOfRatings++; } else { rateFace(target->getFace(i),tmp); } } #ifdef DEMATCH cout<<"gr2"<getNrOfFaces()<<" "<getNrOfFaces()< targets) { #ifdef DEMATCH cout<<"grF"<getCycle()->getLines())); double targetArea = 0.0; double sumOverlaps = 0.0; double HausdorffTmp = 0.0; vector sourcel = source->getCycle()->getLines(); for(unsigned int i = 0; i < targets.size(); i++) { vector targetl = ( (Face*) targets[i])->getCycle()->getLines(); if(Utils :: getHausdorfDistance(source->getCycle()->getLines(), ((Face*) targets[i])->getCycle()->getLines()) > HausdorffTmp) { HausdorffTmp = Utils :: getHausdorfDistance(sourcel, targetl); } targetArea += abs(Utils :: getArea(targetl)); sumOverlaps += Utils :: getOverlap(&sourcel, &targetl); } #ifdef DEMATCH cout<<"grF1 "< children; children = source->getCycle()->getChildren(); #ifdef DEMATCH cout<<"grF2"< tmp = getMatches(children.at(i)); #ifdef DEMATCH cout << "CHTN :" << children.at(i)->hashCode() << " hat " << tmp.size() << " Matches" << endl; #endif if(tmp.size() == 0) { Hausdorffrating += Utils :: getDiameter(sourcel); Ovelaprating += 0.0; Arearating += 0.0; linearRating += 0.5; NrOfRatings++; } else { rateCHTN(children.at(i),tmp); } } #ifdef DEMATCH cout << "GRFace oH AR: " << Arearating << " HR: " << Hausdorffrating << " lR: " << linearRating << " Nr: " << NrOfRatings<getNrOfHoles(); i++) { vector tmp = getMatches(source->getHole(i)); #ifdef DEMATCH cout << "Hole :" << source->getHole(i)->hashCode() << " hat " << tmp.size() << " Matches" << endl; #endif if(tmp.size() == 0) { Hausdorffrating += Utils :: getDiameter (Utils :: convertCHLine2LineWA(sourcel)); Ovelaprating += 0.0; Arearating += 0.0; linearRating += 0.5; NrOfRatings++; } else { rateCHTN(source->getHole(i),tmp); } } #ifdef DEMATCH cout << "GRFace AR: " << Arearating << " HR: " << Hausdorffrating << " lR: " << linearRating << " Nr: " << NrOfRatings << endl; #endif } /* 1.1 rateCHTN() */ void Match::rateCHTN(ConvexHullTreeNode *source,vector targets) { #ifdef DEMATCH cout<<"grCHTN"<getLines().size()<getLines().size(); #endif double sourceArea = abs(Utils :: getArea(source->getLines())); double targetArea = 0.0; double sumOverlaps = 0.0; double HausdorffTmp = 0.0; for(unsigned int i = 0;i < targets.size(); i++) { if(Utils :: getHausdorfDistance(source->getLines(), ((ConvexHullTreeNode*) targets[i])->getLines()) > HausdorffTmp) { HausdorffTmp = Utils :: getHausdorfDistance(source->getLines(), ((ConvexHullTreeNode*) targets[i])->getLines()); } targetArea += abs(Utils :: getArea(((ConvexHullTreeNode*) targets[i])->getLines())); vector sourcel = source->getLines(); vector targetl =((ConvexHullTreeNode*) targets[i])->getLines(); sumOverlaps += Utils :: getOverlap(&sourcel, &targetl); } NrOfRatings++; Arearating += min(sourceArea, targetArea) / max(sourceArea, targetArea); Ovelaprating += sumOverlaps / (sourceArea + targetArea); Hausdorffrating += HausdorffTmp / targets.size(); linearRating += 1.0 / targets.size(); vector children = source->getChildren(); for(unsigned int i = 0; i tmp = getMatches(children.at(i)); if(tmp.size() == 0) { Hausdorffrating += Utils :: getDiameter (Utils :: convertCHLine2LineWA(source->getLines())); Ovelaprating += 0.0; Arearating += 0.0; linearRating += 0.5; NrOfRatings++; } else { rateCHTN(children.at(i), tmp); } } #ifdef DEMATCH cout << "GRCHTN AR: " << Arearating << " HR: " << Hausdorffrating << " lR: " << linearRating << " Nr: " << NrOfRatings << endl; #endif } /* 1 Private Methods 1.1 findIndex() */ int Match :: findIndex(RegionTreeNode *source) { int sourceHash = source->hashCode(); while(maps.find(sourceHash) != maps.end() && !maps[sourceHash]->getSource()->equals(source)) { #ifdef DEMATCH cout << "Konflikt zwischen " << maps.size() << " " << sourceHash << endl; #endif sourceHash++; } #ifdef DEMATCH cout << "second; maps.erase(sourceHash); map :: iterator iter = maps.begin(); while(iter != maps.end()) { SingleMatch *tmp = (*iter).second; for(int i = 0; i < tmp->getNrTargets(); i++) { if(toDelete->equals(tmp->getTargetAt(i))) tmp->removeTarget(i); } iter++; } } } }