00001
00006 #ifdef HAVE_CONFIG_H
00007 #include <tumble-conf.h>
00008 #endif
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
00021
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
00072
00073
00074 static unsigned long id_counter = 0;
00077 Cell::Cell() : id(id_counter++)
00078 {
00079 }
00080
00081
00082
00083
00084
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
00145 const EdgeCell *VertexCell::get_any_edge() const {
00146 assert(!edges_.empty());
00147
00148
00149 return edges_.back();
00150 }
00151 EdgeCell *VertexCell::get_any_edge() {
00152 assert(!edges_.empty());
00153 return edges_.back();
00154 }
00155
00156
00157
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
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
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
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
00497 if( get_spline()->closed ) {
00498 return get_vertex(0)->get_bezier();
00499 }
00500
00501
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
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
00571 if(i<0 || i>=num+2) return NULL;
00572
00573
00574 if(i==0) return get_d0_vertex(0);
00575
00576
00577 if(i>0 && i<=num) return get_d1_vertex(i-1);
00578
00579
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
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
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
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
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
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
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
00987 if(containment_dimension() == 1) {
00988 return get_u();
00989 }
00990
00991
00992
00993
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
01005
01006
01007
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
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
01230 Point2D v1 = get_cp(1) - get_cp(0);
01231 Point2D v2 = get_cp(2) - get_cp(1);
01232
01233
01234 double v1mag= v1.mag();
01235 double v2mag = v2.mag();
01236
01237 if (v1mag == 0 || v2mag == 0)
01238 return 0.0;
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
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
01458
01459
01460
01461
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
01479 std::vector<BezierVertex*> v;
01480 v.reserve(3);
01481
01482
01483
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
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
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
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
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
01538
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
01546
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
01557
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
01868
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
01897 cos_threshold = cos(get_min_angle() * (PI/180.0));
01898
01899
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
01907 if ((e0->is_boundary() && e1->is_boundary())
01908 && (e0->get_bdry_edge() != e1->get_bdry_edge())) {
01909 continue;
01910 }
01911
01912
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
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
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
01955 if( is_inverted && !is_not_inverted) return 1;
01956
01957
01958 if( !is_inverted && is_not_inverted) return 0;
01959
01960
01961 if( !is_inverted && !is_not_inverted)
01962 return -1;
01963
01964
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
01987
01988
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
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
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();
02058
02059 double cr = (cc-a).mag();
02060 double abdist = (a-b).mag();
02061 double bcdist = (b-c).mag();
02062 double acdist = (a-c).mag();
02063
02064
02065 Point2D mp = (a+b)*0.5;
02066 double se = abdist;
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
02080 Point2D vec = (cc-mp);
02081 vec /= vec.mag();
02082 Point2D offcenter = (mp + (vec * (2.0 * beta * se)));
02083
02084
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
02180 assert(0);
02181 return -1;
02182 }
02183
02184
02185
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
02201
02202
02203
02204
02205
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
02356
02357
02358
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
02389
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
02412
02413
02414
02415 if( diff < newton_optimal_tolerance || (niter == (int)newton_iterations && diff < newton_tolerance) ){
02416
02417
02418
02419
02420
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
02433
02434
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
02441
02442 return ((u >= 0.0) && (v >= 0.0)
02443 && (u+v <= 1.0 + newton_zero_tolerance));
02444 }
02445 }
02446 niter = -1;
02447
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 }