state.cc

Go to the documentation of this file.
00001 #include "state.h"
00002 
00003 #include <cmath>
00004 #include <iostream>
00005 
00006 #include "box.h"
00007 #include "container.h"
00008 #include "edge.h"
00009 #include "face.h"
00010 #include "gain_schedule.h"
00011 #include "intersecting_faces.h"
00012 #include "space.h"
00013 #include "vertex.h"
00014 #include "virtual_disp.h"
00015 
00016 using std::cout;
00017 using std::endl;
00018 
00019 State * State::only_one = NULL;
00020 
00021 State & State::instance(void)
00022 {
00023   // Not thread-safe.
00024   // -- lock mutex
00025   if (only_one == NULL)
00026     only_one = new State();
00027   // -- unlock mutex
00028   return *only_one;
00029 }
00030 
00031 State::State (const State& rhs)
00032   :nb(),
00033   ae(),ea(),vd2(0)
00034 {
00035   cout << "Assignment operator prohibited on instances of State class.\n";
00036   cout << "State " << rhs.nb.size()<< endl;
00037   exit(0);
00038 }
00039 
00040 State::State (void)
00041   :nb(),
00042   ae(),ea(),vd2(0)
00043 {
00044   ae.reserve(VECTOR_RESERVE);
00045 };
00046 
00047 State& State::operator= (const State& rhs)
00048 {
00049   cout << "Copy assignment operator prohibited on instances of State class.\n";
00050   cout << "State " << rhs.nb.size() << endl;
00051   exit(0);
00052 }
00053 
00054 double State::getVD2 (void)
00055 {
00056   return vd2;
00057 }
00058 
00059 void State::setVD2 (double d)
00060 {
00061   vd2 = d;
00062 }
00063 
00064 //void State::addVertexToSetNiceCheck (Vertex * v)
00065 //{
00066 //  ni.insert(const_cast<Vertex*>(v));
00067 //}
00068 
00069 //void State::addVertexToFullSearch (Vertex * v)
00070 //{
00071 //  fs.insert(v);
00072 //}
00073 
00074 void State::clearNewFaces (void)
00075 {
00076   nb.clear();
00077 }
00078 
00079 //void State::clearSetNiceCheck (void)
00080 //{
00081 //  ni.clear();
00082 //}
00083 
00084 void State::addNewFace (Face * const f,Box * const b)
00085 {
00086   nb.insert(std::make_pair(f,b));
00087 }
00088 
00089 //hv_it State::ni_begin (void)
00090 //{
00091 //  return ni.begin();
00092 //}
00093 //
00094 //hv_it State::ni_end (void)
00095 //{
00096 //  return ni.end();
00097 //}
00098 
00099 mmap_fp_bp State::getOrigBoxesOfVertAdjFaces (Vertex * const v)
00100 {
00101   vec_bp vbp;
00102   //ob.clear();
00103   mmap_fp_bp ob;
00104   // for each adjacent face
00105   for(fp_cit i=v->begin();i!=v->end();i++)
00106   {
00107     // get boxes that overlap this face's bounding box
00108     vbp.clear();
00109     Space::instance().getBoxesToCheck(*i,vbp);
00110     // add box*s to multimap ob
00111     for(bp_it j=vbp.begin();j!=vbp.end();j++)
00112     {
00113       ob.insert(std::make_pair(*i,*j));
00114     }
00115   }
00116   return ob;
00117 }
00118 
00126 vec_vp State::getVertsForFullClosestPtSearch (Vertex const * const v)
00127 {
00128   double bb[6];
00129   v->getBoundingBox(bb);
00130   vec_d origin(3,0),end(3,0);
00131   origin[0] = bb[0]-(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00132   origin[1] = bb[2]-(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00133   origin[2] = bb[4]-(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00134   end[0]    = bb[1]+(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00135   end[1]    = bb[3]+(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00136   end[2]    = bb[5]+(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00137   vec_bp bp;
00138   Space::instance().getBoxesFromPosition(origin,end,bp);
00139 
00140   vec_vp fs;
00141   fs.reserve(VECTOR_RESERVE);
00142   vec_vp t;
00143   t.reserve(VECTOR_RESERVE);
00144   // for each box
00145   for(bp_it i=bp.begin();i!=bp.end();i++)
00146   {
00147     // for each face in box
00148     for(fp_cit j=(*i)->begin();j!=(*i)->end();j++)
00149     {
00150       // add face vertices to vector
00151       t.push_back((*j)->getVertex(0));
00152       t.push_back((*j)->getVertex(1));
00153       t.push_back((*j)->getVertex(2));
00154     }
00155   }
00156   // sort and keep unique vertices
00157   sort(t.begin(),t.end());
00158   t.assign(t.begin(),unique(t.begin(),t.end()));
00159   // for each vertex in vector
00160   for(vp_it j=t.begin();j!=t.end();j++)
00161   {
00162     // if face vertex is not frozen, has a closest point and
00163     // closest point lies on an adjacent face of active vertex, v
00164     // then add vertex to affected vertex set
00165     if( (Container::instance().vertexIsFrozen(*j)==false)
00166         && (*j)->getFace()!=NULL && binary_search(v->begin(),v->end(),(*j)->getFace()) )
00167     {
00168       fs.push_back(*j);
00169     }
00170   }
00171   // adjacent vertices to current vertex need full search for closest point
00172   // since vertx normal will have changed
00173   t.clear();
00174   // for each face in box
00175   for(fp_cit k=v->begin();k!=v->end();k++)
00176   {
00177     // add face vertices to vector
00178     t.push_back((*k)->getVertex(0));
00179     t.push_back((*k)->getVertex(1));
00180     t.push_back((*k)->getVertex(2));
00181   }
00182   // sort and keep unique vertices
00183   sort(t.begin(),t.end());
00184   t.assign(t.begin(),unique(t.begin(),t.end()));
00185   // for each vertex in vector
00186   for(vp_it j=t.begin();j!=t.end();j++)
00187   {
00188     // if face vertex is not frozen
00189     // then add vertex to affected vertex set
00190     if( (Container::instance().vertexIsFrozen(*j)==false) )
00191     {
00192       fs.push_back(*j);
00193     }
00194   }
00195   return fs;
00196 }
00197 
00205 vec_vp State::getVertsForPartialClosestPtSearch (Vertex const * const v)
00206 {
00207   double bb[6];
00208   v->getBoundingBox(bb);
00209   vec_d origin(3,0),end(3,0);
00210   origin[0] = bb[0]-(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00211   origin[1] = bb[2]-(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00212   origin[2] = bb[4]-(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00213   end[0]    = bb[1]+(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00214   end[1]    = bb[3]+(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00215   end[2]    = bb[5]+(NUM_ADJACENT_BOXES*SPACE_LENGTH)*SCALE;
00216   vec_bp bp;
00217   Space::instance().getBoxesFromPosition(origin,end,bp);
00218 
00219   vec_vp ps;
00220   ps.reserve(VECTOR_RESERVE);
00221   // for each box
00222   for(bp_it i=bp.begin();i!=bp.end();i++)
00223   {
00224     // for each face in box
00225     for(fp_cit j=(*i)->begin();j!=(*i)->end();j++)
00226     {
00227       // for each vertex of face
00228       for(int k=0;k<3;k++)
00229       {
00230         // store face vertices
00231         ps.push_back((*j)->getVertex(k));
00232       }
00233     }
00234   }
00235   // sort and keep unique 
00236   sort(ps.begin(),ps.end());
00237   ps.assign(ps.begin(),unique(ps.begin(),ps.end()));
00238   // DEBUG
00239 //  cout << "State::getVertsForPartialClosestPtSearch:\n"
00240 //       << "vertex bounding box ["
00241 //       << bb[0] << " "
00242 //       << bb[1] << " "
00243 //       << bb[2] << " "
00244 //       << bb[3] << " "
00245 //       << bb[4] << " "
00246 //       << bb[5] << "]\n"
00247 //       << "grab boxes from this region ["
00248 //       << origin[0] << " "
00249 //       << end[0]    << " "
00250 //       << origin[1] << " "
00251 //       << end[1]    << " "
00252 //       << origin[2] << " "
00253 //       << end[2]    << "]\n"
00254 //       << "num vertices in partial search = " << ps.size() << endl;
00255   // DEBUG
00256   return ps;
00257 }
00258 
00259 void State::collectEdgeAngles (Vertex const * const v)
00260 {
00261   ea.clear();
00263   // for each adjacent face of current vertex
00264   for(fp_cit i=v->begin();i!=v->end();i++)
00265   {
00266     ea[(*i)->getEdge(0)] = (*i)->getEdge(0)->getAngle();
00267     ea[(*i)->getEdge(1)] = (*i)->getEdge(1)->getAngle();
00268     ea[(*i)->getEdge(2)] = (*i)->getEdge(2)->getAngle();
00269   }
00270 }
00271 
00280 void State::updateClosestFaceToVertices (Vertex * const v,vec_vp & fs,vec_vp & ps)
00281 {
00282   double dummy[3] = {0.0,0.0,0.0};
00283   // sort and keep unique 
00284   sort(fs.begin(),fs.end());
00285   fs.assign(fs.begin(),unique(fs.begin(),fs.end()));
00286   // DEBUG
00287   //bool found = false;
00288   //for(vp_it i=fs.begin();i!=fs.end();i++)
00289   //{
00290   //  if((*i)->isMatch(TARGET_VERTEX_INDEX_1,TARGET_VERTEX_NAME_1)==true) found=true;
00291   //}
00292   //if(found==true)
00293   //{
00294   //  cout << "\n\n\ntarget vertex found in full_search vector.\n";
00295   //}
00296   //else
00297   //{
00298   //  cout << "\n\n\ntarget vertex NOT found in full_search vector.\n";
00299   //}
00300   //found = false;
00301   //for(vp_it i=ps.begin();i!=ps.end();i++)
00302   //{
00303   //  if((*i)->isMatch(TARGET_VERTEX_INDEX_1,TARGET_VERTEX_NAME_1)==true) found=true;
00304   //}
00305   //if(found==true)
00306   //{
00307   //  cout << "target vertex found in partial_search vector.\n";
00308   //}
00309   //else
00310   //{
00311   //  cout << "target vertex NOT found in partial_search vector.\n";
00312   //}
00313   // DEBUG
00314   // for each collected vertex requiring full closest point search
00315   for(vp_it i=fs.begin();i!=fs.end();i++)
00316   {
00317     // if vertex is not frozen
00318     if(Container::instance().vertexIsFrozen(*i)==false)
00319     {
00320       // DEBUG
00321       //if((*i)->isMatch(TARGET_VERTEX_INDEX_1,TARGET_VERTEX_NAME_1)==true)
00322       //{
00323       //  cout << "\ntarget vertex will be processed as full_search.\n";
00324       //  if((*i)->getFace()==NULL)
00325       //  {
00326       //    cout << "target vertex closest face started as NULL.\n";
00327       //  }
00328       //  else
00329       //  {
00330       //    cout << "target vertex closest face started as follows.\n";
00331       //    (*i)->getFace()->print(cout);
00332       //  }
00333       //}
00334       // DEBUG
00335       Face *cl=NULL;
00336       vec_d p;
00337       double sqd=0.0;
00338       bool flag = Container::instance().findClosestPtToVertex(*i,p,sqd,cl);
00339       if (flag==true)
00340       {
00341         (*i)->setFace(cl);
00342       }
00343       else
00344       {
00345         (*i)->setFace(NULL);
00346       }
00347       // DEBUG
00348       //if((*i)->isMatch(TARGET_VERTEX_INDEX_1,TARGET_VERTEX_NAME_1)==true)
00349       //{
00350       //  if(flag==true)
00351       //  {
00352       //    cout << "closest point wad found on following face.\n";
00353       //    cout << "separation distance = " << sqrt(sqd) << ".\n";
00354       //    cl->print(cout);
00355       //  }
00356       //  else
00357       //  {
00358       //    cout << "closest point was NOT found.\n";
00359       //  }
00360       //}
00361       // DEBUG
00362       Virtual_Disp::instance().updateVirtualDisp(*i,flag);
00363       // update global energy
00364       // false -> do not compute force, hence dummy
00365       double e=(*i)->getSeparationForceEnergy(dummy,false);
00366       //energy=energy-(*i)->getEnergy()+e;
00367       Container::instance().updateEnergy(-(*i)->getEnergy());
00368       Container::instance().updateEnergy(e);
00369       (*i)->setEnergy(e);
00370     }
00371   }
00372   // for each collected vertex not requiring full search
00373   for(vp_it i=ps.begin();i!=ps.end();i++)
00374   {
00375     // if vertex not already processed, i.e. found in fs hashset and not frozen
00376     if((binary_search(fs.begin(),fs.end(),*i)==false) && 
00377        (Container::instance().vertexIsFrozen(*i)==false))
00378     {
00381       vec_d norm = (*i)->getNormal();
00382       bool gate=false;
00383       double squareD = 0.0;
00384       // compute current square of separation distance for collected vertex
00385       if((*i)->getFace()!=NULL){ squareD = (*i)->getSqSepDist(); }
00386       vec_fp cf;
00387       cf.clear();
00388       // for each adjacent face of vertex *v
00389       for(fp_cit j=v->begin();j!=v->end();j++)
00390       {
00391         // if face is not adjacent to collected vertex, *i
00392         if ((*i)->faceIsAdjacent(*j)==false)
00393         {
00394           cf.push_back(*j);
00395         }
00396       }
00397       // DEBUG
00398       //if((*i)->isMatch(TARGET_VERTEX_INDEX_1,TARGET_VERTEX_NAME_1)==true)
00399       //{
00400       //  cout << "target vertex was processed as partial_search.\n"
00401       //        << "beginning separation distance = " << sqrt(squareD) << endl
00402       //        << "number of faces searched = " << cf.size() << endl;
00403       //  cout << "********** faces searched **********\n";
00404       //  for (fp_it j=cf.begin();j!=cf.end();j++)
00405       //  {
00406       //    (*j)->print(cout);
00407       //  }
00408       //  cout << "********** faces searched **********\n";
00409       //  if((*i)->getFace()==NULL)
00410       //  {
00411       //    cout << "target vertex closest face started as NULL.\n";
00412       //  }
00413       //  else
00414       //  {
00415       //    cout << "target vertex closest face started as follows.\n";
00416       //    (*i)->getFace()->print(cout);
00417       //  }
00418       //}
00419       // DEBUG
00420       // if the closest point to current vertex was found on this face
00421       Face *cl=NULL;
00422       //if(Container::instance().computeClosest(*j,*i,squareD,norm,true,dummy3))
00423       vec_d p;
00424       if(Container::instance().findClosestPtToVertexAmongFaces(*i,cf,p,squareD,cl)==true)
00425       {
00426         gate=true;
00427         (*i)->setFace(cl);
00428       }
00429       // if new closest point was found
00430       if(gate)
00431       {
00432         // DEBUG
00433         //if((*i)->isMatch(TARGET_VERTEX_INDEX_1,TARGET_VERTEX_NAME_1)==true)
00434         //{
00435         //  cout << "new closest face was found for target vertex.\n";
00436         //}
00437         // DEBUG
00438         // update global energy
00439         // false -> do not compute force, hence dummy
00440         double e=(*i)->getSeparationForceEnergy(dummy,false);
00441         //energy=energy-(*i)->getEnergy()+e;
00442         Container::instance().updateEnergy(-(*i)->getEnergy());
00443         Container::instance().updateEnergy(e);
00444         (*i)->setEnergy(e);
00445         // update sets with vertex squared virtual displacement
00446         Virtual_Disp::instance().updateSets(*i,(*i)->getSqVirtualDisp(Gain_Schedule::instance().getGain()));
00447       }
00448       else
00449       {
00450         // DEBUG
00451         //if((*i)->isMatch(TARGET_VERTEX_INDEX_1,TARGET_VERTEX_NAME_1)==true)
00452         //{
00453         //  cout << "new closest face was NOT found for target vertex.\n";
00454         //}
00455         // DEBUG
00456       }
00457     }
00458   }
00459 }
00460 
00461 void State::updateAdjacentFaceBoxes (Vertex const * const v,mmap_fp_bp & ob)
00462 {
00463   // for each adjacent face, update Box*s
00464   for(fp_cit k=v->begin();k!=v->end();k++)
00465   {
00466     (*k)->updateBoxes(ob,nb);
00467   }
00468 }
00469 
00470 void State::updateAdjFaceBoundingBoxes (Vertex const * const v)
00471 {
00472   // for each adjacent face, update Box*s
00473   for(fp_cit k=v->begin();k!=v->end();k++)
00474   {
00475     (*k)->setBoundingBox();
00476   }
00477 }
00478 
00479 void State::updateMovedVertexEnergy (Vertex * const v)
00480 {
00481   double dummy[3] = {0.0,0.0,0.0};
00483   // false -> do not compute force, hence dummy
00484   double e=v->getSeparationForceEnergy(dummy,false);
00485   //energy=energy-v->getEnergy()+e;
00486   Container::instance().updateEnergy(-v->getEnergy());
00487   Container::instance().updateEnergy(e);
00488   v->setEnergy(e);
00490   // for each affected edge
00491   for(ep_cit i=ae.begin();i!=ae.end();i++)
00492   {
00493     Vertex *v1=NULL,*v2=NULL,*o1=NULL,*o2=NULL;
00494     (*i)->getVertices(v1,v2,o1,o2);
00495     // choice of v1 is arbitrary, v2 could have been used
00496     // false -> do not compute force, hence dummy
00497     e=(*i)->getStretchForceEnergy(v1,dummy,false)
00498           +(*i)->getAngleForceEnergy(0,dummy,false);
00499     //energy=energy-(*i)->getEnergy()+e;
00500     Container::instance().updateEnergy(-(*i)->getEnergy());
00501     Container::instance().updateEnergy(e);
00502     (*i)->setEnergy(e);
00503   }
00504 }
00505 
00514 void State::updateVertexVD (Vertex * const v)
00515 {
00516   // collect adjacent edges to current vertex
00517   vec_ep e;
00518   v->getAdjacentEdges(e);
00519   // collect edges from current vertex adjacent faces
00520   ae.clear();
00521   for(fp_cit i=v->begin();i!=v->end();i++)
00522   {
00523     // store face edges
00524     ae.push_back((*i)->getEdge(0));
00525     ae.push_back((*i)->getEdge(1));
00526     ae.push_back((*i)->getEdge(2));
00527   }
00528   // sort and keep unique 
00529   sort(ae.begin(),ae.end());
00530   ae.assign(ae.begin(),unique(ae.begin(),ae.end()));
00531   // set for storing nearby vertices to update
00532   v_set nearby;
00533   // for each collected edge from current vertex adjacent faces
00534   for(ep_it i=ae.begin();i!=ae.end();i++)
00535   {
00536     // if edge is not adjacent to current vertex
00537     if( find(e.begin(),e.end(),*i)==e.end())
00538     {
00539       Vertex *v1,*v2,*o1,*o2;
00540       (*i)->getVertices(v1,v2,o1,o2);
00541       // insert all four edge vertices (v1,v2,o1,o2) into set
00542       nearby.insert(v1);
00543       nearby.insert(v2);
00544       nearby.insert(o1);
00545       nearby.insert(o2);
00546     }
00547   }
00548   // update collected vertices including current vertex
00549   // for each collected vertex
00550   for(vs_it i=nearby.begin();i!=nearby.end();i++)
00551   {
00552     // if vertex has a closest point, then update sets
00553     if((*i)->getFace()!=NULL)
00554     {
00555       Virtual_Disp::instance().updateSets(*i,(*i)->getSqVirtualDisp(Gain_Schedule::instance().getGain()));
00556     }
00557   }
00558 }
00559 
00560 bool State::assignNewVertexCoords (Vertex * const v,vec_d const & p,bool &int_flag,bool &angle_flag)
00561 {
00562   Intersecting_Faces & i_f(Intersecting_Faces::instance());
00563   // build old face* hashtable
00564   mmap_fp_bp ob = getOrigBoxesOfVertAdjFaces(v);
00565   // clear new face* hashtable
00566   clearNewFaces();
00567   // store current vertex position
00568   double pO[3]={v->getCoord(0),v->getCoord(1),v->getCoord(2)};
00569   // collect vertices in a local region
00570   // whose closest point is on adjacent face of current vertex
00571   vec_vp fs = getVertsForFullClosestPtSearch(v);
00572   // collect edge angles
00573   collectEdgeAngles(v);
00574   // set current position to holding position
00575   v->setNewPos(p);
00576   // add to previous collection of vertices the collection 
00577   // of all vertices in the same local region as before
00578   // also collect edges of adjacent faces of current vertex
00579   vec_vp ps = getVertsForPartialClosestPtSearch(v);
00580   // if no faces intersect and no edges have small angles
00581   int_flag = (i_f.vertAdjFacesHaveNewInt(v) && INTERSECTION_WEIGHT!=100.0);
00582   angle_flag = State::instance().smallAnglesFound();
00583   if (int_flag==false && angle_flag==false)
00584   {
00585     // for each adjacent face, update Box*s
00586     updateAdjacentFaceBoxes(v,ob);
00587     // for each adjacent face, update bounding box
00588     updateAdjFaceBoundingBoxes(v);
00589     // process intersecting faces, if any
00590     if(i_f.getCountOfIntFaces(false)>0)
00591     {
00592       // store vertices for which niceness may have changed
00593       // i.e. vertices of faces that were intersected
00594       // but now aren't, and vice versa
00595       hashset_v ni = i_f.getNiceCheckSet(v);
00596       // detect niceness changes and collect changed vertices
00597       i_f.getNiceSet(fs,ni);
00598     }
00599     // update closest point and global energy 
00600     // for affected vertices collected before
00601     updateClosestFaceToVertices(v,fs,ps);
00602     // update sets with squared virtual displacement of nearby vertices
00603     updateVertexVD(v);
00604     // update global energy due to this vertex
00605     updateMovedVertexEnergy(v);
00606     // DEBUG
00607 //    if (ENABLE_VTRACK==true)
00608 //    {
00609 //      cout << "Vertices undergoing full closest point search\n"
00610 //           << "*********************************************\n";
00611 //      for (vp_it i=fs.begin();i!=fs.end();i++)
00612 //      {
00613 //        (*i)->print(cout);
00614 //      }
00615 //      cout << "*********************************************\n";
00616 //      cout << "Vertices undergoing partial closest point search\n"
00617 //           << "*********************************************\n";
00618 //      for (vp_it i=ps.begin();i!=ps.end();i++)
00619 //      {
00620 //        (*i)->print(cout);
00621 //      }
00622 //      cout << "*********************************************\n";
00623 //      cout << "num verts in full    search = " << fs.size() << endl
00624 //           << "num verts in partial search = " << ps.size() << endl;
00625 //    }
00626     // DEBUG
00627     return true;
00628   }
00629   else
00630   {
00631     // move vertex back
00632     v->setPos(pO[0],pO[1],pO[2]);
00633     return false;
00634   }
00635 }
00636 
00637 bool State::smallAnglesFound (void) const
00638 {
00639   // for each element in hashtable (edge*->double)
00640   for(edhm_cit j=ea.begin();j!=ea.end();j++)
00641   {
00642     // if edge angle is less than threshold
00643     // and if angle change is in wrong direction, then return true
00644     double new_angle=(*j).first->getAngle();
00645     // small new_angles are acceptable if old_angle was also small and angle is improving
00646     // if new angle is small
00647     if (fabs(new_angle)<EDGE_ANGLE_THRESHOLD || fabs(2*PI-new_angle)<EDGE_ANGLE_THRESHOLD)
00648     {
00649       // if old angle is not small or angle change is wrong, then return true
00650       if(   !(fabs((*j).second)<EDGE_ANGLE_THRESHOLD  ||
00651          fabs(2*PI-(*j).second)<EDGE_ANGLE_THRESHOLD) ||
00652             angleChangeIsWrong((*j).second,new_angle) )
00653       {
00654         return true;
00655       }
00656     }
00657   }
00658   // no adjacent edges of current vertex violate edge angle threshold
00659   return false;
00660 }
00661 
00662 bool State::angleChangeIsWrong (double old_angle,double new_angle) const
00663 {
00664   if (old_angle < PI)
00665   {
00666     // angle should increase towards PI
00667     // angle increase is correct
00668     // if angle increases, return false
00669     // if angle decreases, return true
00670     if ( new_angle>old_angle )  {return false;}
00671     else                        {return true;} 
00672   }
00673   else
00674   {
00675     // assume old_angle > PI, i.e. not exactly PI
00676     // angle should decrease towards PI
00677     // angle decrease is correct
00678     // if angle decreases, return false
00679     // if angle increases, return true
00680     if ( new_angle<old_angle )  {return false;}
00681     else                        {return true;} 
00682   }
00683 }
00684 

Generated on Fri Jul 18 19:43:40 2008 for meshmorph by  doxygen 1.5.1