cell.C

Go to the documentation of this file.
00001 
00006 #ifdef HAVE_CONFIG_H
00007 #include <tumble-conf.h>
00008 #endif /* HAVE_CONFIG_H */
00009 
00010 #include <iostream>
00011 
00012 #include "cell.h"
00013 
00014 #include "datastore.h"
00015 #include "spline.h"
00016 #include "util.h"
00017 
00018 using namespace std;
00019 
00020 /* Print out the result of each iteration in newton_find */
00021 //#define DEBUG_NEWTON_FIND
00022 
00026 #define define_iterators_any(cls, cell, plural, out) \
00027   cls::cell##_iterator cls::begin_##plural() { \
00028     return cell##_iterator(super::begin_##plural()); \
00029   } \
00030   cls::cell##_const_iterator cls::begin_##plural() const { \
00031     return cell##_const_iterator(super::begin_##plural()); \
00032   } \
00033   cls::cell##_iterator cls::end_##plural() { \
00034     return cell##_iterator(super::end_##plural()); \
00035   } \
00036   cls::cell##_const_iterator cls::end_##plural() const { \
00037     return cell##_const_iterator(super::end_##plural()); \
00038   } \
00039   out *cls::get_any_##cell() { \
00040     return static_cast<out*>(super::get_any_##cell()); \
00041   } \
00042   const out *cls::get_any_##cell() const { \
00043     return static_cast<const out*>(super::get_any_##cell()); \
00044   }
00045 
00049 #define define_iterators_canon(cls, cell, plural, out) \
00050   cls::cell##_iterator cls::begin_##plural() { \
00051     return cell##_iterator(super::begin_##plural()); \
00052   } \
00053   cls::cell##_const_iterator cls::begin_##plural() const { \
00054     return cell##_const_iterator(super::begin_##plural()); \
00055   } \
00056   cls::cell##_iterator cls::end_##plural() { \
00057     return cell##_iterator(super::end_##plural()); \
00058   } \
00059   cls::cell##_const_iterator cls::end_##plural() const { \
00060     return cell##_const_iterator(super::end_##plural()); \
00061   } \
00062   out *cls::get_canon_##cell() { \
00063     return static_cast<out*>(super::get_canon_##cell()); \
00064   } \
00065   const out *cls::get_canon_##cell() const { \
00066     return static_cast<const out*>(super::get_canon_##cell()); \
00067   }
00068 
00069 
00070 /*******************************************/
00071 /*                Cell                     */
00072 /*******************************************/
00073 
00074 static unsigned long id_counter = 0; 
00077 Cell::Cell() : id(id_counter++)
00078 {
00079 }
00080 
00081 
00082 
00083 /*******************************************/
00084 /*                VertexCell               */
00085 /*******************************************/
00090 VertexCell::VertexCell(PersistantStore& store) : edges_(store)
00091 {
00092   edges_.reserve(6);
00093 }
00094 
00096 VertexCell::~VertexCell()
00097 {
00098 }
00099 
00103 void VertexCell::add_edge(EdgeCell *e)
00104 {
00105   assert(e);
00106   assert(!has_edge(e));
00107   edges_.push_back(e);
00108 }
00109 
00114 void VertexCell::delete_edge(EdgeCell *e)
00115 {
00116   assert(e);
00117   edge_iterator it = find(begin_edges(), end_edges(), e);
00118   assert(it != end_edges());
00119   edges_.erase(it);
00120 }
00121 
00123 bool VertexCell::has_edge(const EdgeCell *e) const
00124 {
00125   edge_const_iterator it = find(begin_edges(), end_edges(), e);
00126   return (it != end_edges());
00127 }
00128 
00130 struct hasfacep {
00131   const FaceCell *f_;
00132   hasfacep(const FaceCell *f) : f_(f) { }
00133   bool operator()(const EdgeCell *e) const {
00134     return e->has_face(f_);
00135   }
00136 };
00137 
00138 bool VertexCell::has_face(const FaceCell *f) const
00139 {
00140   edge_const_iterator it = find_if(begin_edges(), end_edges(), hasfacep(f));
00141   return (it != end_edges());
00142 }
00143 
00144 /* !\brief Get some edge, doesn't matter which one.  */
00145 const EdgeCell *VertexCell::get_any_edge() const {
00146   assert(!edges_.empty());
00147   // return the back in case the call is going to be
00148   // followed by delete_edge
00149   return edges_.back();
00150 }
00151 EdgeCell *VertexCell::get_any_edge() {
00152   assert(!edges_.empty());
00153   return edges_.back();
00154 }
00155 
00156 /*******************************************/
00157 /*                EdgeCell                 */
00158 /*******************************************/
00159 
00161 EdgeCell::EdgeCell(PersistantStore& store, VertexCell *v0, VertexCell *v1)
00162 : vertices_(store), faces_(store)
00163 {
00164   for (int i = 0; i < 2; i++){
00165     faces_.access(i) = NULL;
00166   }
00167   vertices_.access(0) = v0;
00168   vertices_.access(1) = v1;
00169 }
00170 
00171 
00179 void EdgeCell::add_face(FaceCell *f)
00180 {
00181   assert(num_faces() < 2);
00182   assert(!has_face(f));
00183   for(int i = 0 ; i < 2; i++) {
00184     if(faces_[i] == NULL) {
00185       faces_.access(i) = f;
00186       return;
00187     }
00188   }
00189   assert(0);
00190 }
00191 
00197 void EdgeCell::delete_face(FaceCell *f)
00198 {
00199   if(f==faces_[0]){
00200     faces_.access(0) = faces_[1];
00201     faces_.access(1) = NULL;
00202   }
00203   else if(f==faces_[1]){
00204     faces_.access(1) = NULL;
00205   }
00206   else {
00207     assert(0);
00208   }
00209 }
00210 
00212 bool EdgeCell::has_vertex(const VertexCell *v) const
00213 {
00214     for(int i=0; i<2; i++) if(v == vertices_[i]) return true;
00215     return false;
00216 }
00217 
00219 bool EdgeCell::has_face(const FaceCell *f) const
00220 {
00221     for(int i=0; i<2; i++) if(f == faces_[i]) return true;
00222     return false;
00223 }
00224 
00226 int EdgeCell::num_faces() const
00227 {
00228     int num=0;
00229     if(faces_[0]) num++;
00230     if(faces_[1]) num++;
00231     return num;
00232 }
00233 
00234 VertexCell *EdgeCell::get_canon_vertex()
00235 {
00236   assert(vertices_[0] != NULL);
00237   return vertices_[0];
00238 }
00239 
00240 const VertexCell *EdgeCell::get_canon_vertex() const
00241 {
00242   assert(vertices_[0] != NULL);
00243   return vertices_[0];
00244 }
00245 
00246 FaceCell *EdgeCell::get_any_face()
00247 {
00248   assert(faces_[0] != NULL);
00249   return faces_[0];
00250 }
00251 
00252 const FaceCell *EdgeCell::get_any_face() const
00253 {
00254   assert(faces_[0] != NULL);
00255   return faces_[0];
00256 }
00257 
00258 /*******************************************/
00259 /*              FaceCell                   */
00260 /*******************************************/
00261 
00267 FaceCell::FaceCell(PersistantStore& store) : edges_(store)
00268 {
00269   edges_.reserve(3);
00270 }
00271 
00273 FaceCell::~FaceCell()
00274 {
00275 }
00276 
00283 void FaceCell::add_edge(EdgeCell *e)
00284 {
00285   assert(e);
00286   assert(!has_edge(e));
00287   edges_.push_back(e);
00288 }
00289 
00295 void FaceCell::delete_edge(EdgeCell *e)
00296 {
00297   edge_iterator it = find(begin_edges(), end_edges(), e);
00298   assert(it != end_edges());
00299   edges_.erase(it);
00300 }
00301 
00302 struct hasvertexp {
00303   const VertexCell *v_;
00304   hasvertexp(const VertexCell *v) : v_(v) { }
00305   bool operator()(const EdgeCell *e) const {
00306     return e->has_vertex(v_);
00307   }
00308 };
00309 
00311 bool FaceCell::has_vertex(const VertexCell *v) const
00312 {
00313   return find_if(begin_edges(), end_edges(), hasvertexp(v)) != end_edges();
00314 }
00315 
00317 bool FaceCell::has_edge(const EdgeCell *e) const
00318 {
00319   return find(begin_edges(), end_edges(), e) != end_edges();
00320 }
00321 
00322 const EdgeCell *FaceCell::get_canon_edge() const {
00323   assert(num_edges() != 0);
00324   return *begin_edges();
00325 }
00326 
00327 EdgeCell *FaceCell::get_canon_edge() {
00328   assert(num_edges() != 0);
00329   return *begin_edges();
00330 }
00331 
00332 /*******************************************/
00333 /*              BoundaryVertex             */
00334 /*******************************************/
00339 BoundaryVertex::BoundaryVertex(PersistantStore& store, const ControlPoint& cp)
00340   : VertexCell(store), bezier_vertex_(NULL), cp_(cp), fixed_(FixedNone)
00341 {
00342 }
00343 
00345 void BoundaryVertex::increase_fixed(Movement fixed)
00346 {
00347   switch(fixed) {
00348     case FixedNone:
00349       return;
00350     case FixedHorizontal:
00351       switch(get_fixed()) {
00352         case FixedNone:
00353         case FixedHorizontal:
00354           fixed_ = FixedHorizontal;
00355           return;
00356         case FixedVertical:
00357         case FixedAll:
00358           fixed_ = FixedAll;
00359           return;
00360       }
00361       assert(0);
00362     case FixedVertical:
00363       switch(get_fixed()) {
00364         case FixedNone:
00365         case FixedVertical:
00366           fixed_ = FixedVertical;
00367           return;
00368         case FixedHorizontal:
00369         case FixedAll:
00370           fixed_ = FixedAll;
00371           return;
00372       }
00373       assert(0);
00374     case FixedAll:
00375       fixed_ = FixedAll;
00376       return;
00377   }
00378   assert(0);
00379 }
00380 
00382 void BoundaryVertex::set_bezier(BezierVertex *bez)
00383 {
00384     assert(get_bezier() == NULL);
00385     bezier_vertex_ = bez;
00386 }
00387 
00389 void BoundaryVertex::set_cp(const Point2D &p)
00390 {
00391   access_cp() = p;
00392 }
00393 
00395 const Point2D& BoundaryVertex::get_cp() const
00396 {
00397     return *cp_;
00398 }
00399 Point2D& BoundaryVertex::access_cp()
00400 {
00401     return cp_.access();
00402 }
00403 
00404 const BezierVertex *BoundaryVertex::get_bezier() const
00405 {
00406   return bezier_vertex_;
00407 }
00408 BezierVertex *BoundaryVertex::get_bezier() {
00409   return bezier_vertex_;
00410 }
00411 
00412 const ControlPoint& BoundaryVertex::get_control_point() const
00413 {
00414     return cp_;
00415 }
00416 
00417 Movement BoundaryVertex::get_fixed() const
00418 {
00419   return fixed_;
00420 }
00421 
00423 void BoundaryVertex::print() const
00424 {
00425    std::cout<<*this;
00426 }
00427 
00429 ostream& operator<<( ostream &stream, const BoundaryVertex& v)
00430 {
00431   stream<<"BoundryVertex["<<&v<<"]: {point:="<< v.get_cp() <<", edges:=[";
00432   bool first = true;
00433   for(BoundaryVertex::edge_const_iterator it = v.begin_edges();
00434       it != v.end_edges(); ++it) {
00435     if (!first) { stream << ", "; } else { first = false; }
00436     stream << *it;
00437   }
00438   stream<<"] fixed:="<<v.get_fixed()
00439           <<", bezier_vertex:="<<v.get_bezier()<<" }"<<endl;
00440   return stream;
00441 }
00442 
00443 define_iterators_any(BoundaryVertex, edge, edges, BoundaryEdge);
00444 
00445 /*******************************************/
00446 /*               BoundaryEdge              */
00447 /*******************************************/
00448 
00458 BoundaryEdge::BoundaryEdge(PersistantStore& store,
00459                            BoundaryVertex *v0,
00460                            BoundaryVertex *v1,
00461                            const std::vector<ControlPoint> &deboor,
00462                            const std::vector<double> &knots,
00463                            DataStore *datastore)
00464 : EdgeCell(store, v0, v1),
00465   spline_(new QBSpline(deboor, knots, datastore, (v0 == v1))),
00466   fixed_(FixedNone),
00467   color_(0)
00468 {
00469 }
00470 
00472 BoundaryEdge::~BoundaryEdge()
00473 {
00474   delete spline_;
00475 }
00476 
00477 
00492 const BezierVertex* BoundaryEdge::get_d0_vertex(int i) const
00493 {
00494     assert(i >= 0); assert(i < 2);
00495 
00496     /* Closed splines should have the same BoundaryVertex for both vertexs */
00497     if( get_spline()->closed ) {
00498       return get_vertex(0)->get_bezier();
00499     }
00500 
00501     /* Use the QBSpline::b vector to find which of the vertexs is the first */
00502     ControlPoint tofind;
00503     switch(i) {
00504       case 0: tofind = get_spline()->b[0]; break;
00505       case 1: tofind = get_spline()->b.back(); break;
00506       default: assert(0);
00507     }
00508     /* Find the vertex on which get_control_point() returns tofind. */
00509     for(vertex_const_iterator it = begin_vertices(); it != end_vertices();++it){
00510       if ((*it)->get_control_point() == tofind) {
00511         return (*it)->get_bezier();
00512       }
00513     }
00514     assert(0);
00515     return NULL;
00516 }
00517 
00518 BezierVertex* BoundaryEdge::get_d0_vertex(int i) {
00519   return const_cast<BezierVertex*>(
00520       const_cast<const BoundaryEdge*>(this)->get_d0_vertex(i));
00521 }
00522 
00529 int BoundaryEdge::get_num_d1_vertexs() const
00530 {
00531     return get_spline()->vertexs.size();
00532 }
00533 
00543 const BezierVertex* BoundaryEdge::get_d1_vertex(int i) const
00544 {
00545     assert(i >= 0); assert(i < get_num_d1_vertexs());
00546     return get_spline()->vertexs[i];
00547 }
00548 BezierVertex* BoundaryEdge::get_d1_vertex(int i) {
00549   return const_cast<BezierVertex*>(
00550       const_cast<const BoundaryEdge*>(this)->get_d1_vertex(i));
00551 }
00552 
00567 const BezierVertex* BoundaryEdge::get_bezier_vertex(int i) const
00568 {
00569     int num = get_num_d1_vertexs();
00570     /* out of range */
00571     if(i<0 || i>=num+2) return NULL;
00572 
00573     /* first D0 */
00574     if(i==0) return get_d0_vertex(0);
00575 
00576     /* D1 */
00577     if(i>0 && i<=num) return get_d1_vertex(i-1);
00578 
00579     /* Last D0 */
00580     return get_d0_vertex(1);
00581 }
00582 BezierVertex* BoundaryEdge::get_bezier_vertex(int i) {
00583   return const_cast<BezierVertex*>(
00584       const_cast<const BoundaryEdge*>(this)->get_bezier_vertex(i));
00585 }
00586 
00596 void BoundaryEdge::set_fixed(Movement fixed)
00597 {
00598     fixed_ = fixed;
00599     get_vertex(0)->increase_fixed(fixed);
00600     get_vertex(1)->increase_fixed(fixed);
00601 }
00602 
00611 void BoundaryEdge::set_color(int color)
00612 {
00613     color_ = color;
00614 }
00615 
00620 void BoundaryEdge::set_restlength(double restlength)
00621 {
00622     get_spline()->restlength = restlength;
00623 }
00624 
00633 const BoundaryVertex* BoundaryEdge::get_vertex(int i) const
00634 {
00635   return static_cast<const BoundaryVertex*>(super::get_vertex(i));
00636 }
00637 BoundaryVertex* BoundaryEdge::get_vertex(int i)
00638 {
00639   return static_cast<BoundaryVertex*>(super::get_vertex(i));
00640 }
00641 
00642 const QBSpline *BoundaryEdge::get_spline() const
00643 {
00644   return spline_;
00645 }
00646 
00647 QBSpline *BoundaryEdge::get_spline()
00648 {
00649   return spline_;
00650 }
00651 
00652 Movement BoundaryEdge::get_fixed() const
00653 {
00654   return fixed_;
00655 }
00656 
00657 int BoundaryEdge::get_color() const
00658 {
00659   return color_;
00660 }
00661 
00663 void BoundaryEdge::print() const
00664 {
00665     std::cout<<*this;
00666 }
00667 
00669 ostream &operator<<( ostream &stream, const BoundaryEdge& e){
00670   bool first;
00671   stream << "BoundaryEdge[" << &e << "]: {Vertices:=[";
00672   first = true;
00673   for(BoundaryEdge::vertex_const_iterator it = e.begin_vertices();
00674       it != e.end_vertices(); ++it) {
00675     if(!first) { stream << ", "; } else { first = false; }
00676     stream << *it;
00677   }
00678   stream <<"], Faces:=[";
00679   first = true;
00680   for(BoundaryEdge::face_const_iterator it = e.begin_faces();
00681       it != e.end_faces(); ++it) {
00682     if(!first) { stream << ", "; } else { first = false; }
00683     stream << *it;
00684   }
00685   stream << "], fixed:=" << e.get_fixed() << ", color:=" << e.get_color()
00686          << "}\n" << *e.get_spline();
00687     return stream;
00688 }
00689 
00690 define_iterators_canon(BoundaryEdge, vertex, vertices, BoundaryVertex);
00691 define_iterators_any(BoundaryEdge, face, faces, BoundaryFace);
00692 
00693 /*******************************************/
00694 /*               BoundaryFace              */
00695 /*******************************************/
00696 
00698 BoundaryFace::BoundaryFace(PersistantStore& store,
00699                            double min_angle, int color) : FaceCell(store),
00700                                               min_angle_(min_angle),
00701                                               color_(color)
00702 {
00703 }
00704 
00706 void BoundaryFace::set_min_angle(double min_angle)
00707 {
00708     min_angle_ = min_angle;
00709 }
00710 
00712 void BoundaryFace::set_color(int color)
00713 {
00714     color_ = color;
00715 }
00716 
00717 double BoundaryFace::get_min_angle() const
00718 {
00719   return min_angle_;
00720 }
00721 
00722 int BoundaryFace::get_color() const
00723 {
00724   return color_;
00725 }
00726 
00728 void BoundaryFace::print() const
00729 {
00730     std::cout<<*this;
00731 }
00732 
00733 
00735 ostream &operator<<( ostream &stream, const BoundaryFace& f){
00736     stream<<"BoundaryFace["<<&f<<"]: { Edges:=[";
00737     bool first = true;
00738     for(BoundaryFace::edge_const_iterator it = f.begin_edges();
00739         it != f.end_edges(); ++it) {
00740       if(!first) { stream << ", "; } else { first = false; }
00741       stream << *it;
00742     }
00743     stream<<"] min_angle:=" << f.get_min_angle()
00744           <<" color:=" << f.get_color() << "}\n";
00745     return stream;
00746 }
00747 
00748 define_iterators_canon(BoundaryFace, edge, edges, BoundaryEdge);
00749 
00750 /*******************************************/
00751 /*               BezierVertex              */
00752 /*******************************************/
00753 
00755 BezierVertex::BezierVertex(PersistantStore& store,
00756                            const ControlPoint& cp, const DataPoint& dp)
00757   : VertexCell(store), cp_(cp), dp_(dp)
00758   , bdry_edge_(NULL), bdry_vertex_(NULL), u_(-1.0)
00759 {
00760 }
00761 
00763 void BezierVertex::set_cp(const Point2D &p )
00764 {
00765     access_cp() = p;
00766 }
00767 
00769 void BezierVertex::set_dp(const LinearData &d )
00770 {
00771     access_dp() = d;
00772 }
00773 
00775 void BezierVertex::set_data(int pos, double data)
00776 {
00777     access_dp().set(data, pos);
00778 }
00779 
00781 double BezierVertex::get_data(int pos) const
00782 {
00783     return get_dp()[pos];
00784 }
00785 
00786 
00795 int BezierVertex::containment_dimension() const
00796 {
00797     if( bdry_vertex_ ) return 0;
00798     if( bdry_edge_ ) return 1;
00799     return 2;
00800 }
00801 bool BezierVertex::is_boundary() const
00802 {
00803   return containment_dimension() < 2;
00804 }
00805 
00810 const Point2D& BezierVertex::get_cp() const
00811 {
00812     return *cp_;
00813 }
00814 
00816 Point2D& BezierVertex::access_cp()
00817 {
00818     return cp_.access();
00819 }
00820 
00821 ControlPoint BezierVertex::get_control_point() const
00822 {
00823   return cp_;
00824 }
00825 
00830 const LinearData& BezierVertex::get_dp() const
00831 {
00832     return *dp_;
00833 }
00834 
00836 LinearData& BezierVertex::access_dp()
00837 {
00838     return dp_.access();
00839 }
00840 
00841 DataPoint BezierVertex::get_data_point() const
00842 {
00843   return dp_;
00844 }
00845 
00847 void BezierVertex::print() const
00848 {
00849     std::cout<<*this;
00850 }
00851 
00859 void BezierVertex::set_bdry(BoundaryEdge *b,double param)
00860 {
00861   bdry_vertex_ = NULL;
00862   bdry_edge_ = b;
00863   u_ = param;
00864 
00865   /* register with spline */
00866   b->get_spline()->set_bezier_vertex(get_u(), this);
00867 }
00868 
00869 
00882 void BezierVertex::set_bdry(BoundaryEdge *b,int idx)
00883 {
00884     QBSpline *spline = b->get_spline();
00885     assert( (idx >= 1) && (idx <= (int)spline->k.size()-2) );
00886     bdry_vertex_ = NULL;
00887     bdry_edge_ = b;
00888     u_ = spline->k[idx];
00889 
00890     /* register with spline */
00891     spline->set_bezier_vertex(idx, this);
00892 }
00893 
00900 void BezierVertex::set_bdry(BoundaryVertex *v)
00901 {
00902   bdry_vertex_ = v;
00903   bdry_edge_ = NULL;
00904 
00905   /* register with boundary vertex */
00906   v->set_bezier(this);
00907 }
00908 
00909 const BoundaryEdge *BezierVertex::get_bdry_edge() const
00910 {
00911   assert(containment_dimension() < 2);
00912   return bdry_edge_;
00913 }
00914 
00915 BoundaryEdge *BezierVertex::get_bdry_edge()
00916 {
00917   assert(containment_dimension() < 2);
00918   return bdry_edge_;
00919 }
00920 
00921 const BoundaryVertex *BezierVertex::get_bdry_vertex() const
00922 {
00923   assert(containment_dimension() < 1);
00924   return bdry_vertex_;
00925 }
00926 
00927 BoundaryVertex *BezierVertex::get_bdry_vertex()
00928 {
00929   assert(containment_dimension() < 1);
00930   return bdry_vertex_;
00931 }
00932 
00933 
00947 double BezierVertex::get_u(const BezierEdge *e) const
00948 {
00949     /* fail if this is not one of our edges, or it is not a boundary*/
00950     assert(has_edge(e));
00951     const BoundaryEdge *be = e->get_bdry_edge();
00952     assert(be);
00953     const BezierVertex *opposite;
00954 
00955     if( this == e->get_vertex(0) ) opposite = e->get_vertex(1);
00956     else opposite = e->get_vertex(0);
00957 
00958     return get_u(be,opposite);
00959 }
00960 
00982 double BezierVertex::get_u(const BoundaryEdge *be,
00983                            const BezierVertex *opposite) const
00984 {
00985     assert(containment_dimension() < 2);
00986     /* if this is a D1 vertex simply return known u value */
00987     if(containment_dimension() == 1) {
00988       return get_u();
00989     }
00990 
00991     /* otherwise we are D0 and we need to figure out if we are
00992      * at the beginning or end of the spline, look for our
00993      * opposing vertex and see which end of spline->vertexs it is at
00994      */
00995     const QBSpline *spline = be->get_spline();
00996     int num_verts = spline->k.size()-2;
00997     assert(spline->k.size()-2 == spline->vertexs.size());
00998     if(num_verts > 1){
00999         assert((spline->vertexs[0] == opposite) || (spline->vertexs[num_verts-1] == opposite));
01000         if(spline->vertexs[0] == opposite) return spline->k.front();
01001         else return spline->k.back();
01002     }
01003 
01004     /* if there are one or less D1 vertex in the spline then we will evaluate
01005      * at the first and last knot, and see who is closer to us.
01006      * since there must be at least two D1 vertexs in a closed spline
01007      * these points must be different
01008      */
01009     assert(!spline->closed);
01010     Point2D p  = get_cp();
01011     Point2D p0 = spline->evaluate(spline->k.front());
01012     Point2D p1 = spline->evaluate(spline->k.back());
01013     bool is_first = (p0 - p).mag() < (p1 - p).mag();
01014     if(is_first) return spline->k.front();
01015     else return spline->k.back();
01016 }
01017 
01021 double BezierVertex::get_u() const {
01022   assert(containment_dimension() == 1);
01023   return u_;
01024 }
01025 
01029 void BezierVertex::replace_cp(const ControlPoint& newp) {
01030   cp_ = newp;
01031 }
01032 
01033 
01035 ostream &operator<<( ostream &stream, const BezierVertex& v){
01036     stream<<"BezierVertex "<< &v <<": {control point:="<< v.get_cp()
01037           <<", data point:="<< v.get_dp() <<", edges:=[";
01038     bool first = true;
01039     for(BezierVertex::edge_const_iterator it = v.begin_edges();
01040         it != v.end_edges(); ++it) {
01041       const BezierEdge *e = *it;
01042       stream << (first ? "" : ", ") << e;
01043       first = false;
01044     }
01045 
01046     stream << "], containment dimension " << v.containment_dimension();
01047     switch (v.containment_dimension()) {
01048       case 0:
01049         stream << ", bdry_vertex=" << v.get_bdry_vertex();
01050         break;
01051       case 1:
01052         stream << ", bdry_edge=" << v.get_bdry_edge() << ", u=" << v.get_u();
01053         break;
01054       case 2:
01055         break;
01056       default:
01057         assert(0);
01058     }
01059     stream << "}\n";
01060     return stream;
01061 }
01062 
01063 define_iterators_any(BezierVertex, edge, edges, BezierEdge);
01064 
01065 /*******************************************/
01066 /*               BezierEdge                */
01067 /*******************************************/
01068 
01070 BezierEdge::BezierEdge(PersistantStore& pstore,
01071                        BezierVertex *v1, BezierVertex *v2,
01072                        const ControlPoint& cp,
01073                        const DataStore& dstore)
01074 : EdgeCell(pstore, v1, v2), bdry_edge_(NULL)
01075 {
01076   cp_[0] = v1->get_control_point();
01077   cp_[1] = cp;
01078   cp_[2] = v2->get_control_point();
01079   for(int i = 0; i < get_num_cp(); ++i) {
01080     dp_[i] = dstore[get_control_point(i)];
01081   }
01082   u_[0] = u_[1] = -1.0;
01083 }
01084 
01085 
01091 void BezierEdge::set_bdry(BoundaryEdge *b, double u0, double u1)
01092 {
01093   bdry_edge_ =b;
01094   u_[0] = u0;
01095   u_[1] = u1;
01096 }
01097 
01103 void BezierEdge::replace_cp(const ControlPoint& oldp, const ControlPoint& newp)
01104 {
01105   for (int i = 0; i < get_num_cp(); i++) {
01106     if (cp_[i] == oldp) {
01107       cp_[i] = newp;
01108       return;
01109     }
01110   }
01111   assert(0);
01112 }
01113 
01114 double BezierEdge::get_u(int i) const
01115 {
01116   assert(i >= 0); assert(i < 2);
01117   return u_[i];
01118 }
01119 
01127 Point2D BezierEdge::eval(double u) const
01128 {
01129   double v = 1-u;
01130   Point2D val;
01131   val += get_cp(0) * (v*v);
01132   val += get_cp(1) * (2*u*v);
01133   val += get_cp(2) * (u*u);
01134   return val;
01135 }
01136 
01144 LinearData BezierEdge::dataeval(double u) const
01145 {
01146   double v = 1-u;
01147   LinearData val;
01148   val =  get_dp(0) * (v*v);
01149   val += get_dp(1) * (2*u*v);
01150   val += get_dp(2) * (u*u);
01151   return val;
01152 }
01153 
01163 void BezierEdge::evalIntermediate(double u, Point2D &p, Point2D &pc0, Point2D &pc1) const
01164 {
01165   double v=1-u;
01166   pc0 =  get_cp(0) * v;
01167   pc0 += get_cp(1) * u;
01168 
01169   pc1 =  get_cp(1) * v;
01170   pc1 += get_cp(2) * u;
01171 
01172   p  = pc0 * u;
01173   p += pc1 * v;
01174 }
01175 
01176 
01186 void BezierEdge::dataevalIntermediate(double u, LinearData &d, LinearData &dc0, LinearData &dc1) const
01187 {
01188   double v=1-u;
01189   dc0  = get_dp(0) * v;
01190   dc0 += get_dp(1) * u;
01191 
01192   dc1  = get_dp(1) * v;
01193   dc1 += get_dp(2) * u;
01194 
01195   d =  dc0 * u;
01196   d += dc1 * v;
01197 }
01198 
01199 
01215 bool BezierEdge::is_encroached(const Point2D& p) const
01216 {
01217   typedef Tumble::iterators::dereferencer<const ControlPoint*, const Point2D> 
01218     deref;
01219   return encroaches(p, deref(cp_), deref(cp_ + get_num_cp()));
01220 }
01221 
01227 double BezierEdge::curvature_angle() const
01228 {
01229   // vectors for the control arms
01230   Point2D v1 = get_cp(1) - get_cp(0);
01231   Point2D v2 = get_cp(2) - get_cp(1);
01232 
01233   // vector sizes for normalization
01234   double v1mag= v1.mag();
01235   double v2mag = v2.mag();
01236   // safety
01237   if (v1mag == 0 || v2mag == 0)
01238     return 0.0; // really this is undefined
01239 
01240   double cos_theta = v1.dot(v2) / (v1.mag() * v2.mag());
01241   return acos(cos_theta);
01242 }
01243 
01249 int BezierEdge::left_of_curve(Point2D& p, int stop, double& approx) const
01250 {
01251   approx=0.0;
01252 
01253   Point2D p1 = get_cp(0);
01254   Point2D p2 = get_cp(2);
01255   Point2D ctr = get_cp(1);
01256 
01257   bool convex      = ctr.is_left_of( p1,p2 );
01258   bool carrierside =   p.is_left_of( p1,p2 );
01259   bool leg1side    =   p.is_left_of( p1,ctr);
01260   bool leg2side    =   p.is_left_of( ctr,p2);
01261 
01262   if( carrierside != convex) { return (convex ? 0 : 1); }
01263   if( leg1side == convex)    { return (convex ? 1 : 0); }
01264   if( leg2side == convex)    { return (convex ? 1 : 0); }
01265 
01266   /*now p is inside convex hull of p1,p2,cp*/
01267   double t = 0.5;
01268   double dt = 0.25;
01269   Point2D c1,c2,mp;
01270   bool topside,carrier1,carrier2;
01271   while( stop > 0 ){
01272     c1 = ctr*0.5 + p1*0.5;
01273     c2 = p2*0.5 + ctr*0.5;
01274     mp = c1*0.5 + c2*0.5;
01275 
01276     topside  = p.is_left_of(c1,c2);
01277     carrier1 = p.is_left_of(p1,mp);
01278     carrier2 = p.is_left_of(mp,p2);
01279 
01280     if(topside == convex)    { return (convex ? 1 : 0); }
01281     if(carrier1 == carrier2) { return (convex ? 0 : 1); }
01282 
01283     stop--;
01284     if(carrier1 == convex){
01285       p2 = mp;
01286       ctr = c1;
01287       t -= dt;
01288     }
01289     else{
01290       p1 = mp;
01291       ctr = c2;
01292       t += dt;
01293     }
01294     dt = dt*0.5;
01295   }
01296   approx = t;
01297   return 2;
01298 }
01299 
01304 void BezierEdge::set_cp(const Point2D &p, int i)
01305 {
01306     assert(i>=0 && i<=2);
01307     access_cp(i) = p;
01308 }
01309 
01314 void BezierEdge::set_dp(const LinearData &d, int i)
01315 {
01316     assert(i>=0 && i<=2);
01317     access_dp(i) = d;
01318 }
01319 
01324 const Point2D& BezierEdge::get_cp(int i) const
01325 {
01326     assert(i >= 0); assert(i < get_num_cp());
01327     return *cp_[i];
01328 }
01330 Point2D& BezierEdge::access_cp(int i)
01331 {
01332     assert(i >= 0); assert(i < get_num_cp());
01333     return cp_[i].access();
01334 }
01335 
01337 ControlPoint BezierEdge::get_control_point(int i) const
01338 {
01339   assert(i >= 0); assert(i < get_num_cp());
01340   return cp_[i];
01341 }
01342 
01347 const LinearData& BezierEdge::get_dp(int i) const
01348 {
01349     assert(i >= 0); assert(i < get_num_cp());
01350     return *dp_[i];
01351 }
01352 
01357 LinearData& BezierEdge::access_dp(int i)
01358 {
01359     assert(i >= 0); assert(i < get_num_cp());
01360     return dp_[i].access();
01361 }
01362 
01364 DataPoint BezierEdge::get_data_point(int i) const
01365 {
01366   assert(i >= 0); assert(i < get_num_cp());
01367   return dp_[i];
01368 }
01369 
01375 void BezierEdge::set_data(int i, int pos, double data)
01376 {
01377     assert(i>=0 && i<=2);
01378     access_dp(i).set(data, pos);
01379 }
01380 
01385 const BezierVertex* BezierEdge::get_vertex(int i) const
01386 {
01387     return static_cast<const BezierVertex*>(super::get_vertex(i));
01388 }
01389 BezierVertex* BezierEdge::get_vertex(int i)
01390 {
01391     return static_cast<BezierVertex*>(super::get_vertex(i));
01392 }
01393 
01395 bool BezierEdge::is_boundary() const
01396 {
01397   return bdry_edge_ != NULL;
01398 }
01399 
01400 const BoundaryEdge *BezierEdge::get_bdry_edge() const {
01401   assert(is_boundary());
01402   return bdry_edge_;
01403 }
01404 
01405 BoundaryEdge *BezierEdge::get_bdry_edge() {
01406   assert(is_boundary());
01407   return bdry_edge_;
01408 }
01409 
01411 void BezierEdge::print() const
01412 {
01413     std::cout<<*this;
01414 }
01415 
01417 ostream &operator<<( ostream &stream, const BezierEdge& e){
01418     bool first;
01419     stream<<"BezierEdge "<<&e<<": {cps:=["
01420             << e.get_cp(0) <<","
01421             << e.get_cp(1) <<","
01422             << e.get_cp(2) <<"]"
01423             <<" dps:=["
01424             << e.get_dp(0) <<","
01425             << e.get_dp(1) <<","
01426             << e.get_dp(2) <<"]";
01427     first = true;
01428     stream << " Vertices:=[";
01429     for(BezierEdge::vertex_const_iterator it = e.begin_vertices();
01430         it != e.end_vertices(); ++it) {
01431       if(!first) { stream << ", "; } else { first = false; }
01432       stream << *it;
01433     }
01434     stream <<"], Faces:=[";
01435     first = true;
01436     for(BezierEdge::face_const_iterator it = e.begin_faces();
01437         it != e.end_faces(); ++it) {
01438       if(!first) { stream << ", "; } else { first = false; }
01439       stream << *it;
01440     }
01441 
01442     stream  <<"] ";
01443     if (e.is_boundary()) 
01444       {
01445     stream <<  e.get_bdry_edge()<<" ,u0="<<e.get_u(0)<<" ,u1="<<e.get_u(1);
01446       }
01447     stream << "}\n";
01448     
01449     return stream;
01450 }
01451 
01452 define_iterators_canon(BezierEdge, vertex, vertices, BezierVertex);
01453 define_iterators_any(BezierEdge, face, faces, BezierTriangle);
01454 
01455 
01456 /*******************************************/
01457 /*               BezierTriangle            */
01458 /*******************************************/
01459 
01460 /* map an index [0-2] into an edge's control points to the appropriate
01461    index for the edge, if it were relatively-ccw with the triangle. */
01462 static int map_idx(int i, bool ccw) {
01463   assert(i >= 0); assert(i < 3);
01464   if (ccw) {
01465     return i;
01466   } else {
01467     return 2 - i;
01468   }
01469 }
01470 
01472 BezierTriangle::BezierTriangle(PersistantStore& store,
01473                                BezierEdge * const ein[3],
01474                                const DataStore& datastore,
01475                    bool inverse_handed)
01476 : FaceCell(store), bdry_face_(NULL)
01477 {
01478   /* Discover the three vertices. */
01479   std::vector<BezierVertex*> v;
01480   v.reserve(3);
01481 
01482   /* Discover the orientation of each linear edge: 'true' indicate in that
01483    * the edge is numbered consistent with CCW order, 'false' is CW order. */
01484   bool is_ccw[3];
01485 
01486   if (!inverse_handed) 
01487     {
01488       is_ccw[0] = true;
01489       is_ccw[1] = ( ( ein[1]->get_vertex(0) == ein[0]->get_vertex(1) )
01490             || (ein[1]->get_vertex(1) == ein[0]->get_vertex(0) ) );
01491       is_ccw[2] = ( ( ein[2]->get_vertex(1) == ein[0]->get_vertex(0) )
01492             || (ein[2]->get_vertex(0) == ein[0] -> get_vertex(1) ) );
01493     } else 
01494     {
01495       is_ccw[0] = false;
01496       is_ccw[1] = ( ( ein[1]->get_vertex(0) == ein[0]->get_vertex(0) )
01497             || (ein[1]->get_vertex(1) == ein[0]->get_vertex(1) ) );
01498       is_ccw[2] = ( ( ein[2]->get_vertex(0) == ein[0]->get_vertex(0) )
01499             || (ein[2]->get_vertex(1) == ein[0]->get_vertex(1) ) );
01500     }
01501 
01502   v.push_back(ein[0]->get_vertex(0));
01503   v.push_back(ein[0]->get_vertex(1));
01504   if (ein[1]->get_vertex(0) == v[0] || ein[1]->get_vertex(0) == v[1])
01505     v.push_back(ein[1]->get_vertex(1));
01506   else
01507     v.push_back(ein[1]->get_vertex(0));
01508   
01509   /* Now order the edges themselves (and reorder is_ccw accordingly). */
01510   BezierEdge *e[3];
01511   e[0] = ein[0];
01512   if (ein[0]->get_control_point(map_idx(2, is_ccw[0]))
01513         == ein[1]->get_control_point(map_idx(0, is_ccw[1]))) {
01514     e[1] = ein[1];
01515     e[2] = ein[2];
01516   } else {
01517     // inverse_handed triangle!
01518     assert(ein[0]->get_control_point(map_idx(2, is_ccw[0]))
01519         == ein[2]->get_control_point(map_idx(0, is_ccw[2])));
01520     //assert(0 && "creating an inverse-handed triangle");
01521     e[1] = ein[2];
01522     e[2] = ein[1];
01523     bool tmp = is_ccw[1];
01524     is_ccw[1] = is_ccw[2];
01525     is_ccw[2] = tmp;
01526   }
01527 
01528   /* check that this all matches up */
01529 #ifndef NDEBUG
01530   for(int i = 0; i < 3; i++) {
01531     int j = (i + 1) % 3;
01532     assert(e[i]->get_control_point(map_idx(2, is_ccw[i]))
01533         == e[j]->get_control_point(map_idx(0, is_ccw[j])));
01534   }
01535 #endif
01536 
01537   /* Pick up the control points appropriately, with the fixed edge
01538      numbering. See the doxygen comments for the numbering scheme. */
01539   cp_[0] = e[0]->get_control_point(map_idx(0, is_ccw[0]));
01540   cp_[1] = e[0]->get_control_point(map_idx(1, is_ccw[0]));
01541   cp_[2] = e[0]->get_control_point(map_idx(2, is_ccw[0]));
01542   cp_[3] = e[2]->get_control_point(map_idx(1, is_ccw[2]));
01543   cp_[4] = e[1]->get_control_point(map_idx(1, is_ccw[1]));
01544   cp_[5] = e[1]->get_control_point(map_idx(2, is_ccw[1]));
01545   // check to make sure the numbering is all consistant: at the vertices,
01546   // we have redundancy
01547   assert(cp_[0] == e[2]->get_control_point(map_idx(2, is_ccw[2])));
01548   assert(cp_[2] == e[1]->get_control_point(map_idx(0, is_ccw[1])));
01549   assert(cp_[5] == e[2]->get_control_point(map_idx(0, is_ccw[2])));
01550 
01551   for(int i = 0; i < 6; i++) {
01552     dp_[i] = datastore[cp_[i]];
01553   }
01554 }
01555 
01556 /* !\brief Set the boundary face pointer.
01557  * This can only be called once. */
01558 void BezierTriangle::set_boundary_face(BoundaryFace *f)
01559 {
01560   assert(bdry_face_ == NULL);
01561   assert(f != NULL);
01562   bdry_face_ = f;
01563 }
01564 
01566 const Point2D& BezierTriangle::get_cp(int i) const
01567 {
01568   assert(i >= 0); assert(i < get_num_cp());
01569   return *cp_[i];
01570 }
01571 
01573 Point2D& BezierTriangle::access_cp(int i)
01574 {
01575   assert(i >= 0); assert(i < get_num_cp());
01576   return cp_[i].access();
01577 }
01578 
01580 void BezierTriangle::set_cp(int i, const Point2D& p)
01581 {
01582   access_cp(i) = p;
01583 }
01584 
01585 ControlPoint BezierTriangle::get_control_point(int i) const
01586 {
01587   assert(i >= 0); assert(i < get_num_cp());
01588   return cp_[i];
01589 }
01590 
01592 const LinearData& BezierTriangle::get_dp(int i) const
01593 {
01594   assert(i >= 0); assert(i < get_num_dp());
01595   return *dp_[i];
01596 }
01597 
01599 LinearData& BezierTriangle::access_dp(int i)
01600 {
01601   assert(i >= 0); assert(i < get_num_cp());
01602   return dp_[i].access();
01603 }
01604 
01606 void BezierTriangle::set_dp(int i, const LinearData& d)
01607 {
01608   access_dp(i) = d;
01609 }
01610 
01611 DataPoint BezierTriangle::get_data_point(int i) const
01612 {
01613   assert(i >= 0); assert(i < get_num_dp());
01614   return dp_[i];
01615 }
01616 
01619 BezierEdge *BezierTriangle::get_edge(int i) {
01620   assert(i >= 0); assert(i < get_num_edges());
01621   return begin_edges()[i];
01622 }
01623 const BezierEdge *BezierTriangle::get_edge(int i) const {
01624   assert(i >= 0); assert(i < get_num_edges());
01625   return begin_edges()[i];
01626 }
01627 
01628 bool BezierTriangle::has_bdry_face() const {
01629   return bdry_face_;
01630 }
01631 const BoundaryFace *BezierTriangle::get_bdry_face() const {
01632   assert(has_bdry_face());
01633   return bdry_face_;
01634 }
01635 BoundaryFace *BezierTriangle::get_bdry_face() {
01636   assert(has_bdry_face());
01637   return bdry_face_;
01638 }
01639 BoundaryFace *BezierTriangle::get_bdry_face_or_null() {
01640   return bdry_face_;
01641 }
01642 
01643 double BezierTriangle::get_min_angle() const {
01644   return get_bdry_face()->get_min_angle();
01645 }
01646 int BezierTriangle::get_color() const {
01647   return get_bdry_face()->get_color();
01648 }
01649 
01655 const BezierEdge* BezierTriangle::get_edge(int p0, int p1) const
01656 {
01657     return get_edge(get_edge_index_by_cps(p0,p1));
01658 }
01659 BezierEdge* BezierTriangle::get_edge(int p0, int p1)
01660 {
01661     return get_edge(get_edge_index_by_cps(p0,p1));
01662 }
01663 
01675 Point2D BezierTriangle::eval(double u, double v) const
01676 {
01677   double w=1.0-u-v;
01678   Point2D val;
01679   val  = get_cp(0) * (w * w);
01680   val += get_cp(1) * (2.0 * v * w);
01681   val += get_cp(2) * (v * v);
01682   val += get_cp(3) * (2.0 * u * w);
01683   val += get_cp(4) * (2.0 * u * v);
01684   val += get_cp(5) * (u * u);
01685   return val;
01686 }
01687 
01699 LinearData BezierTriangle::dataeval(double u, double v) const
01700 {
01701   double w=1.0-u-v;
01702   LinearData val;
01703   val =  get_dp(0) * (w * w);
01704   val += get_dp(1) * (2.0 * v * w);
01705   val += get_dp(2) * (v * v);
01706   val += get_dp(3) * (2.0 * u * w);
01707   val += get_dp(4) * (2.0 * u * v);
01708   val += get_dp(5) * (u * u);
01709   return val;
01710 }
01711 
01723 void BezierTriangle::evalIntermediate(double u, double v, Point2D &p, Point2D &pc0, Point2D &pc1, Point2D &pc2) const
01724 {
01725     double w = 1.0-u-v;
01726     pc0 =  get_cp(0) * w;
01727     pc0 += get_cp(3) * u;
01728     pc0 += get_cp(1) * v;
01729 
01730     pc1 =  get_cp(3) * w;
01731     pc1 += get_cp(5) * u;
01732     pc1 += get_cp(4) * v;
01733 
01734     pc2 =  get_cp(1) * w;
01735     pc2 += get_cp(4) * u;
01736     pc2 += get_cp(2) * v;
01737 
01738     p =  pc0 * w;
01739     p += pc1 * u;
01740     p += pc2 * v;
01741 }
01742 
01743 
01755 void BezierTriangle::dataevalIntermediate(double u, double v, LinearData &d, LinearData &dc0, LinearData &dc1, LinearData &dc2) const
01756 {
01757     double w=1.0-u-v;
01758     dc0 =  get_dp(0) * w;
01759     dc0 += get_dp(3) * u;
01760     dc0 += get_dp(1) * v;
01761 
01762     dc1 =  get_dp(3) * w;
01763     dc1 += get_dp(5) * u;
01764     dc1 += get_dp(4) * v;
01765 
01766     dc2 =  get_dp(1) * w;
01767     dc2 += get_dp(4) * u;
01768     dc2 += get_dp(2) * v;
01769 
01770     d =  dc0 * w;
01771     d += dc1 * u;
01772     d += dc2 * v;
01773 }
01774 
01781 double BezierTriangle::jacobian(double u, double v) const
01782 {
01783   Point2D pdu,pdv;
01784   jacobian_matrix(u,v,pdu,pdv);
01785   return -pdu.cross(pdv);
01786 }
01787 
01798 void BezierTriangle::jacobian_matrix(double u,double v,Point2D& pdu,Point2D& pdv) const
01799 {
01800   double w=1.0-u-v;
01801   pdu =  (get_cp(5) - get_cp(3))*u;
01802   pdu += (get_cp(4) - get_cp(1))*v;
01803   pdu += (get_cp(3) - get_cp(0))*w;
01804   pdu *= 2.0;
01805 
01806   pdv =  (get_cp(4) - get_cp(3))*u;
01807   pdv += (get_cp(2) - get_cp(1))*v;
01808   pdv += (get_cp(1) - get_cp(0))*w;
01809   pdv *= 2.0;
01810 }
01811 
01812 static const double large_num = 1.0E9;
01813 
01825 void BezierTriangle::bound_jacobian(double& min, double& max,double& area) const
01826 {
01827   Point2D vu[3];
01828   Point2D vv[3];
01829 
01830   vu[0] = get_cp(3) - get_cp(0);
01831   vu[1] = get_cp(5) - get_cp(3);
01832   vu[2] = get_cp(4) - get_cp(1);
01833   vv[0] = get_cp(1) - get_cp(0);
01834   vv[1] = get_cp(4) - get_cp(3);
01835   vv[2] = get_cp(2) - get_cp(1);
01836 
01837   int i,j;
01838   double cro;
01839   min = large_num;
01840   max = -large_num;
01841   area = 0.0;
01842   for(i=0; i<3; i++){
01843     for(j=0; j<3; j++){
01844       cro = - vu[i].cross(vv[j]);
01845       if( cro < min ) { min = cro; }
01846       if( cro > max ) { max = cro; }
01847       if( i == j ) { cro *= 2.0; }
01848       area += cro;
01849     }
01850   }
01851   area /= 12.0;
01852   return;
01853 }
01854 
01855 bool BezierTriangle::newton_find(const Point2D &p, double &u, double &v, int &niter, int &edge_num)
01856 {
01857     int en;
01858     bool ret = CurvedTriangle::newton_find(p, u, v, niter, en);
01859 
01860     switch(en) {
01861       case -1: edge_num = -1; break;
01862       case 0: edge_num = get_edge_index_by_cps(0, 2); break;
01863       case 1: edge_num = get_edge_index_by_cps(2, 5); break;
01864       case 2: edge_num = get_edge_index_by_cps(5, 0); break;
01865       default: assert(0); break;
01866     }
01867     //if(en>=0) cout<<"Newton Find converged in "<<niter<<" to an external point"<<endl
01868     //    <<"origE#:"<<en<<" newE#:"<<edge_num<<" [u:"<<u<<", v:"<<v<<", u+v:"<<u+v<<"]"<<endl;
01869     return ret;
01870 }
01871 
01873 double BezierTriangle::area() const
01874 {
01875   double dummy1, dummy2, area;
01876   bound_jacobian(dummy1, dummy2, area);
01877   return area;
01878 }
01879 
01888 bool BezierTriangle::small_angle() const
01889 {
01890     double cos_threshold;
01891     int e0_idx, e1_idx;
01892     const BezierEdge *e0, *e1;
01893     const BezierVertex *v0, *v1, *v2, *v3;
01894     double cos_ang;
01895 
01896     /* we are comparing cosines so convert to radians and take cosine */
01897     cos_threshold = cos(get_min_angle() * (PI/180.0));
01898 
01899     /* Iterate over all 3 angles (angles are represented by two adjacent edges)*/
01900     for(int i=0; i<3; ++i){
01901         e0_idx = (0 + i) % 3;
01902         e1_idx = (1 + i) % 3;
01903         e0 = get_edge(e0_idx);
01904         e1 = get_edge(e1_idx);
01905 
01906         /* skip angles that are a result of boundaries */
01907         if ((e0->is_boundary() && e1->is_boundary())
01908             && (e0->get_bdry_edge() != e1->get_bdry_edge())) {
01909           continue;
01910         }
01911 
01912         /* now find vertexs of e0 and e1 so that v1 is the shared vertex */
01913         v0 = e0->get_vertex(0);
01914         v1 = e0->get_vertex(1);
01915         v2 = e1->get_vertex(0);
01916         v3 = e1->get_vertex(1);
01917         if(v2 == v0){
01918             v0 = v1;
01919             v1 = v2;
01920             v2 = v3;
01921         }
01922         else if(v2 == v1){
01923             v2 = v3;
01924         }
01925         else if(v3 == v0){
01926             v0 = v1;
01927             v1 = v3;
01928         }
01929         /* find cosine of angle */
01930         cos_ang = v1->get_cp().angle(v0->get_cp(), v2->get_cp());
01931 
01932         if( (cos_ang > 0.0) && (cos_ang > cos_threshold) ){
01933           //cout<<"Triangle angle "<<i<<" is small: "<<(180.0/PI)*acos(cos_ang)<<endl;
01934           return true;
01935         }
01936     }
01937     return false;
01938 }
01939 
01940 bool BezierTriangle::is_linear_inverted() const
01941 {
01942   Point2D a = get_cp(0);
01943   Point2D b = get_cp(2);
01944   Point2D c = get_cp(5);
01945 
01946   return c.is_left_of(b,a);
01947 }
01948 
01949 int BezierTriangle::is_inverted() const
01950 {
01951     bool is_inverted = is_definitely_inverted();
01952     bool is_not_inverted = is_definitely_not_inverted();
01953 
01954     /* definitely Inverted */
01955     if( is_inverted && !is_not_inverted) return 1;
01956 
01957     /* Definitely _NOT_ inverted */
01958     if( !is_inverted && is_not_inverted) return 0;
01959 
01960     /* This is the indecisive case */
01961     if( !is_inverted && !is_not_inverted)
01962       return -1;
01963 
01964     /* This case should never happen */
01965     if( is_inverted && is_not_inverted ) {
01966       assert(0);
01967     }
01968     return -2;
01969 }
01970 
01971 bool BezierTriangle::is_definitely_inverted() const
01972 {
01973     if( jacobian(0.0, 0.0) < 0.0 ) return true;
01974     if( jacobian(0.0, 1.0) < 0.0 ) return true;
01975     if( jacobian(1.0, 0.0) < 0.0 ) return true;
01976     if( jacobian(1.0/3.0, 1.0/3.0) < 0.0 ) return true;
01977 
01978     for(int i=0; i<7; i++){
01979       if( jacobian(ALPHA[i], BETA[i]) < 0.0 ) return true;
01980     }
01981     return false;
01982 }
01983 
01984 bool BezierTriangle::is_definitely_not_inverted() const
01985 {
01986     /* These are the control points for the jacobian determinate
01987      * thus they are the coefficients for the jacobian dterminate in the Beizer basis
01988      * as long as all of these are positive then the jacobian determinate must be positive
01989      */
01990 
01991     Point2D vu[3];
01992     Point2D vv[3];
01993 
01994     vu[0] = get_cp(3) - get_cp(0);
01995     vu[1] = get_cp(5) - get_cp(3);
01996     vu[2] = get_cp(4) - get_cp(1);
01997     vv[0] = get_cp(1) - get_cp(0);
01998     vv[1] = get_cp(4) - get_cp(3);
01999     vv[2] = get_cp(2) - get_cp(1);
02000 
02001     int i,j,k;
02002     for(i=0; i<3; i++){
02003       if( vv[i].cross(vu[i]) < 0.0 )
02004     return false;
02005       // This means a corner control point of the jacobian is negative
02006 
02007       j = (i+1) % 3;
02008       k = (i+2) % 3;
02009       if (vv[j].cross(vu[k]) + vv[k].cross(vu[j]) < 0.0)
02010       return false;
02011       // This means a midside control point of the jacobian is negative
02012     }
02013     return true;
02014 }
02015 
02019 Point2D BezierTriangle::circumcenter()  const
02020 {
02021     Point2D a = get_cp(0);
02022     Point2D b = get_cp(2);
02023     Point2D c = get_cp(5);
02024 
02025     double c13 = 0.5 * ( c - a ).dot( c + a );
02026     double c23 = 0.5 * ( c - b ).dot( c + b );
02027     double dety = ( c[ 0 ] - a[ 0 ] ) * c23 - ( c[ 0 ] - b[ 0 ] ) * c13;
02028     double detx = ( c[ 1 ] - b[ 1 ] ) * c13 - ( c[ 1 ] - a[ 1 ] ) * c23;
02029     double det = ( c[ 0 ] - a[ 0 ] ) * ( c[ 1 ] - b[ 1 ] ) - ( c[ 0 ] - b[ 0 ] ) * ( c[ 1 ] - a[ 1 ] );
02030     Point2D p( detx / det, dety / det );
02031     return p;
02032 }
02033 
02039 Point2D BezierTriangle::offcenter() const
02040 {
02041   double min_ang_radians = get_min_angle() * (PI/180.0);
02042   if (min_ang_radians == 0.0) return offcenter(100.0);
02043   double beta = 0.5 / sin(min_ang_radians);
02044 
02045   return offcenter(beta);
02046 }
02047 
02052 Point2D BezierTriangle::offcenter(double beta) const
02053 {
02054   Point2D a = get_cp(0);
02055   Point2D b = get_cp(2);
02056   Point2D c = get_cp(5);
02057   Point2D cc = circumcenter(); // get circumcenter
02058 
02059   double cr = (cc-a).mag(); //get circumradius
02060   double abdist = (a-b).mag();
02061   double bcdist = (b-c).mag();
02062   double acdist = (a-c).mag();
02063 
02064   // Find the midpoint of the shortest edge and the length of the shortest edge
02065   Point2D mp = (a+b)*0.5; // The midpoint of the shortest edge
02066   double se = abdist; // The length of the shortest edge
02067   if (acdist < bcdist) {
02068     if (acdist < abdist) {
02069       mp = (a+c)*0.5;
02070       se = acdist;
02071     }
02072   } else {
02073     if (bcdist < abdist) {
02074       mp = (b+c)*0.5;
02075       se = bcdist;
02076     }
02077   }
02078 
02079   // vec is a vector normal to the shortest edge pointing toward the circumcenter
02080   Point2D vec = (cc-mp);
02081   vec /= vec.mag();
02082   Point2D offcenter = (mp + (vec * (2.0 * beta * se)));
02083 
02084   // If the circumcenter is nearer than the offcenter, use the circumcenter
02085   if (cr > 2.0 * beta*se) {
02086     return offcenter;
02087   } else {
02088     return cc;
02089   }
02090 }
02091 
02093 void BezierTriangle::print() const
02094 {
02095     std::cout<<*this;
02096 }
02097 
02099 void BezierTriangle::print_mathematica() const
02100 {
02101     cout<<"{";
02102     cout<<"{"<<get_cp(0).x()<<", "<<get_cp(0).y()<<"}, ";
02103     cout<<"{"<<get_cp(2).x()<<", "<<get_cp(2).y()<<"}, ";
02104     cout<<"{"<<get_cp(5).x()<<", "<<get_cp(5).y()<<"}, ";
02105     cout<<"{"<<get_cp(1).x()<<", "<<get_cp(1).y()<<"}, ";
02106     cout<<"{"<<get_cp(4).x()<<", "<<get_cp(4).y()<<"}, ";
02107     cout<<"{"<<get_cp(3).x()<<", "<<get_cp(3).y()<<"}";
02108     cout<<"}"<<endl;
02109 }
02110 
02112 ostream &operator<<( ostream &stream, const BezierTriangle &t )
02113 {
02114   stream<<"BezierTriangle "<<&t<<": {cps:=["
02115           << t.get_cp(0) <<","
02116           << t.get_cp(1) <<","
02117           << t.get_cp(2) <<","
02118           << t.get_cp(3) <<","
02119           << t.get_cp(4) <<","
02120           << t.get_cp(5) <<"]"
02121           <<", dps:=["
02122           << t.get_dp(0) <<","
02123           << t.get_dp(1) <<","
02124           << t.get_dp(2) <<","
02125           << t.get_dp(3) <<","
02126           << t.get_dp(4) <<","
02127           << t.get_dp(5) <<"]"
02128           <<", edges:=[";
02129 
02130   stream<<"[";
02131   bool first = true;
02132   for(BezierTriangle::edge_const_iterator it = t.begin_edges();
02133       it != t.end_edges(); ++it) {
02134     if(!first) { stream << ", "; } else { first = false; }
02135     stream << *it;
02136   }
02137   stream << "]";
02138   if (t.has_bdry_face()) {
02139     stream << "bdry_face:=" << t.get_bdry_face();
02140   }
02141   stream << " }\n";
02142   return stream;
02143 }
02144 
02148 define_iterators_canon(BezierTriangle, edge, edges, BezierEdge);
02149 
02165 int BezierTriangle::get_edge_index_by_cps(int p0, int p1) const
02166 {
02167     assert(p0 == 0 || p0 == 2 || p0 == 5);
02168     assert(p1 == 0 || p1 == 2 || p1 == 5);
02169     ControlPoint tp0 = get_control_point(p0);
02170     ControlPoint tp1 = get_control_point(p1);
02171     for(int i = 0; i < get_num_edges(); ++i) {
02172         const BezierEdge *e = get_edge(i);
02173         ControlPoint v0cp = e->get_vertex(0)->get_control_point();
02174         ControlPoint v1cp = e->get_vertex(1)->get_control_point();
02175         if((tp0 == v0cp  && tp1 == v1cp) || (tp1 == v0cp  && tp0 == v1cp)) {
02176           return i;
02177         }
02178     }
02179     /* couldn't find the two points! */
02180     assert(0);
02181     return -1;
02182 }
02183 
02184 /* !\brief For use during bootstrapping only: replace a control point.
02185  * The control point must be found.
02186  */
02187 void BezierTriangle::replace_cp(const ControlPoint& oldp,
02188                                 const ControlPoint& newp)
02189 {
02190   for (int i = 0; i < get_num_cp(); i++) {
02191     if (get_control_point(i) == oldp) {
02192       cp_[i] = newp;
02193       return;
02194     }
02195   }
02196   assert(0);
02197 }
02198 
02199 
02200 /* Ghost triangle methods duplicate BezierTriangle methods only
02201  * CPs and DPs are true Point2D and LinearData, not pointers
02202  */
02203 
02204 /*******************************************/
02205 /*               GhostTriangle             */
02206 /*******************************************/
02207 
02209 GhostTriangle::GhostTriangle(const BezierTriangle &bt)
02210 {
02211     for(int i=0; i < 6; i++){
02212         cp[i] = bt.get_cp(i);
02213         dp[i] = bt.get_dp(i);
02214     }
02215 }
02216 
02218 GhostTriangle::GhostTriangle()
02219 {
02220 }
02221 
02223 void GhostTriangle::set_cp(int i, Point2D p)
02224 {
02225   cp[i] = p;
02226 }
02227 
02229 Point2D GhostTriangle::get_cp(int i) const
02230 {
02231   return cp[i];
02232 }
02233 
02242 double GhostTriangle::jacobian(double u, double v) const
02243 {
02244   Point2D pdu,pdv;
02245   jacobian_matrix(u,v,pdu,pdv);
02246   return -pdu.cross(pdv);
02247 }
02248 
02258 void GhostTriangle::jacobian_matrix(double u, double v, Point2D &pdu, Point2D &pdv) const
02259 {
02260     double w = 1.0-u-v;
02261     pdu =  (cp[5] - cp[3])*u;
02262     pdu += (cp[4] - cp[1])*v;
02263     pdu += (cp[3] - cp[0])*w;
02264     pdu *= 2.0;
02265 
02266     pdv =  (cp[4] - cp[3])*u;
02267     pdv += (cp[2] - cp[1])*v;
02268     pdv += (cp[1] - cp[0])*w;
02269     pdv *= 2.0;
02270 }
02271 
02280 Point2D GhostTriangle::eval(double u, double v) const
02281 {
02282   double w=1.0-u-v;
02283   Point2D val;
02284   val = cp[0] * (w * w);
02285   val += cp[1] * (2.0 * v * w);
02286   val += cp[2] * (v * v);
02287   val += cp[3] * (2.0 * u * w);
02288   val += cp[4] * (2.0 * u * v);
02289   val += cp[5] * (u * u);
02290   return val;
02291 }
02292 
02301 LinearData GhostTriangle::dataeval(double u, double v) const
02302 {
02303   double w=1.0-u-v;
02304   LinearData val;
02305   val =  dp[0] * (w * w);
02306   val += dp[1] * (2.0 * v * w);
02307   val += dp[2] * (v * v);
02308   val += dp[3] * (2.0 * u * w);
02309   val += dp[4] * (2.0 * u * v);
02310   val += dp[5] * (u * u);
02311   return val;
02312 }
02313 
02315 void GhostTriangle::print() const
02316 {
02317     cout<<*this;
02318 }
02319 
02321 void GhostTriangle::print_mathematica() const
02322 {
02323     cout<<"{";
02324     cout<<"{"<<cp[0].x()<<", "<<cp[0].y()<<"}, ";
02325     cout<<"{"<<cp[2].x()<<", "<<cp[2].y()<<"}, ";
02326     cout<<"{"<<cp[5].x()<<", "<<cp[5].y()<<"}, ";
02327     cout<<"{"<<cp[1].x()<<", "<<cp[1].y()<<"}, ";
02328     cout<<"{"<<cp[4].x()<<", "<<cp[4].y()<<"}, ";
02329     cout<<"{"<<cp[3].x()<<", "<<cp[3].y()<<"}";
02330     cout<<"}"<<endl;
02331 }
02332 
02334 ostream &operator<<( ostream &stream, const GhostTriangle &t )
02335 {
02336   stream<<"GhostTriangle "<<&t<<": {cps:=["
02337       << t.cp[0] <<","
02338       << t.cp[1] <<","
02339       << t.cp[2] <<","
02340       << t.cp[3] <<","
02341       << t.cp[4] <<","
02342       << t.cp[5] <<"]"
02343       <<", dps:=["
02344       << t.dp[0] <<","
02345       << t.dp[1] <<","
02346       << t.dp[2] <<","
02347       << t.dp[3] <<","
02348       << t.dp[4] <<","
02349       << t.dp[5] <<"]"<<endl;
02350   return stream;
02351 }
02352 
02353 
02354 /*******************************************/
02355 /*               CurvedTriangle            */
02356 /*******************************************/
02357 
02358 /* These are global values for newton find */
02359 static const double newton_optimal_tolerance = 1.0E-12;
02360 static const double newton_zero_tolerance = 1.0E-5;
02361 static const double newton_tolerance = 1.0E-6;
02362 static const unsigned newton_iterations = 30;
02363 
02383 bool CurvedTriangle::newton_find(const Point2D& p,double& u,double& v, int& niter, int &edge_num) const
02384 {
02385     Point2D pdu, pdv, pt;
02386     double dJinv;
02387     double diff;
02388     //double w;
02389     //double temp;
02390 
02391     u = 0.33;
02392     v = 0.33;
02393     edge_num = -1;
02394 #ifdef DEBUG_NEWTON_FIND
02395     cout << "[NewtonFind] searching for " << p << " in " << this << endl;
02396 #endif
02397     for(niter=1; niter <= (int)newton_iterations; niter++) {
02398         jacobian_matrix(u,v,pdu,pdv);
02399 
02400         pt = eval(u,v) - p;
02401         dJinv = 1.0 / pdv.cross(pdu);
02402         u += dJinv * pt.cross(pdv);
02403         v += dJinv * pdu.cross(pt);
02404 
02405         diff = pt.magsq();
02406 #ifdef DEBUG_NEWTON_FIND
02407         cout << "[NewtonFind " << niter << "] (" << u << ", " << v << ")"
02408           << " = " << eval(u,v) << " ; diff=" << diff << endl;
02409 #endif
02410 
02411         /* Check for convergence within optimal tolerance band.
02412          * If this is our last iteration, then prepare to sacrifice some tolerance to get a convergence
02413          * at less optimal tolerance levels.
02414          */
02415         if( diff < newton_optimal_tolerance || (niter == (int)newton_iterations && diff < newton_tolerance) ){
02416             /* Now that we have converged, check that the parameters of our convergence are within
02417              * the triangle.
02418              *
02419              * If a value is within newton_zero_tolerance of the cut-off then set it to be
02420              * exactly the cut-off value
02421              */
02422             if( fabs(u) < newton_zero_tolerance ) u = 0.0;
02423             if( fabs(v) < newton_zero_tolerance ) v = 0.0;
02424         if( fabs(u+v-1.0) < newton_zero_tolerance ) {
02425               assert(u != 0.0 || v != 0.0);
02426           if (v > 1.0)
02427         v = 1.0 - u;
02428           else
02429         u = 1.0 - v;
02430         }
02431 
02432             //cout<<"In "<<niter<<" iterations: Converged to: u="<<u<<" v="<<v<<" w="<<1.0-u-v<<" with tol="<<diff<<endl;
02433 
02434             /* Return which edge we have crossed over or are on. */
02435             if( u <= 0.0) edge_num = 0;
02436             else if( u+v >= 1.0 - newton_zero_tolerance) edge_num = 1;
02437             else if( v <= 0.0) edge_num = 2;
02438             else edge_num = -1;
02439 
02440             /* Return true if we have converged in the parameter space of the
02441              * triangle, false otherwise. */
02442             return ((u >= 0.0) && (v >= 0.0)
02443                 && (u+v <= 1.0 + newton_zero_tolerance));
02444         }
02445     }
02446     niter = -1;
02447     //cout<<"Convergence failure!"<<"[u:"<<u<<", v:"<<v<<", u+v:"<<u+v<<"]"<<endl;
02448     return false;
02449 }
02450 
02451 bool CurvedTriangle::newton_find(const Point2D& p,double& u,double& v) const
02452 {
02453     int niter;
02454     int edge;
02455     return newton_find(p, u, v, niter, edge);
02456 }

Generated on Mon May 24 09:53:30 2010 for TUMBLE by  doxygen 1.5.2