00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef PLIB_NURBS_SURFACE_SOURCE
00027 #define PLIB_NURBS_SURFACE_SOURCE
00028
00029
00030 #include <surface.h>
00031 #include "matrixMat.h"
00032 #include <math.h>
00033
00036 namespace PLib {
00037
00071 template <class T, int N>
00072 T ParaSurface<T,N>::minDist2(const Point_nD<T,N>& p, T& guessU, T& guessV,T error,T s,int sep,int maxIter, T um, T uM, T vm, T vM) const {
00073 T d,d1,d2 ;
00074 Point_nD<T,N> p2 ;
00075 p2 = pointAt(guessU,guessV) ;
00076 d = norm2(p-p2) ;
00077 d2 = d1 = 0 ;
00078 int niter = 0 ;
00079 T u1,u2 ;
00080 T v1,v2 ;
00081 T step ;
00082 step = 2.0*s/(T)sep ;
00083 u1 = guessU-s ;
00084 u2 = guessU+s ;
00085 v1 = guessV-s ;
00086 v2 = guessV+s ;
00087 while(d>error && niter<maxIter) {
00088 if(u1<um)
00089 u1=um;
00090 if(u2>uM)
00091 u2 = uM ;
00092 if(v1<vm)
00093 v1 = vm ;
00094 if(v2>vM)
00095 v2 = vM ;
00096 T u,v ;
00097 d2 = d1 ;
00098 for(u=u1;u<u2;u+=step)
00099 for(v=v1;v<v2;v+=step){
00100 p2 = pointAt(u,v) ;
00101 d1 = norm2(p-p2) ;
00102 if(d1<d){
00103 d = d1 ;
00104 guessU = u ;
00105 guessV = v ;
00106 }
00107 }
00108 s /= 2.0 ;
00109 u1 = guessU - s ;
00110 u2 = guessU + s ;
00111 v1 = guessV - s ;
00112 v2 = guessV + s ;
00113 step = 2.0*s/(T)sep ;
00114 if(d-d2==0) niter = maxIter ;
00115 if(step<error) niter = maxIter ;
00116 ++niter;
00117 }
00118 return d ;
00119 }
00120
00154 template <class T, int N>
00155 T ParaSurface<T,N>::minDist2b(const Point_nD<T,N>& p, T& guessU, T& guessV,T error,T s,int sep,int maxIter, T um, T uM, T vm, T vM) const {
00156 T d,d1,d2 ;
00157 Point_nD<T,N> p2 ;
00158 p2 = pointAt(guessU,guessV) ;
00159 d = norm2(p-p2) ;
00160 d2 = d1 = 0 ;
00161 int niter = 0 ;
00162 T u1,u2 ;
00163 T v1,v2 ;
00164 T step ;
00165 step = 2.0*s/(T)sep ;
00166 u1 = guessU-s ;
00167 u2 = guessU+s ;
00168 v1 = guessV-s ;
00169 v2 = guessV+s ;
00170 while(d>error && niter<maxIter) {
00171 if(u1<um)
00172 u1=um;
00173 if(u2>uM)
00174 u2 = uM ;
00175 if(v1<vm)
00176 v1 = vm ;
00177 if(v2>vM)
00178 v2 = vM ;
00179 T u,v ;
00180 d2 = d1 ;
00181 for(u=u1;u<=u2;u+=step)
00182 for(v=v1;v<=v2;v+=step){
00183 p2 = pointAt(u,v) ;
00184 d1 = norm2(p-p2) ;
00185 if(d1<d){
00186 d = d1 ;
00187 guessU = u ;
00188 guessV = v ;
00189 }
00190 }
00191 s = step ;
00192 u1 = guessU - s ;
00193 u2 = guessU + s ;
00194 v1 = guessV - s ;
00195 v2 = guessV + s ;
00196 step = s/2.0 ;
00197 if(d-d2==0) niter = maxIter ;
00198 if(step<error) niter = maxIter ;
00199 ++niter;
00200 }
00201 return d ;
00202
00203 }
00204
00205 template <class T, int N>
00206 inline T to2power_xy(const Point_nD<T,N> &p){
00207 return (p.x()*p.x())+(p.y()*p.y()) ;
00208 }
00209
00249 template <class T, int N>
00250 T ParaSurface<T,N>::minDist2xy(const Point_nD<T,N>& p, T& guessU, T& guessV,T error,T dU,T s,int sepU,int sepV,int maxIter, T um, T uM, T vm, T vM) const {
00251 T d,d1,d2,dz ;
00252 Point_nD<T,N> p2 ;
00253 p2 = pointAt(guessU,guessV) ;
00254 d = to2power_xy(p-p2) ;
00255 dz = to2power(p.z()-p2.z()) ;
00256 d2 = d1 = 0 ;
00257 int niter = 0 ;
00258 T u1,u2 ;
00259 T v1,v2 ;
00260 T stepU,stepV ;
00261 if(sepU>0){
00262 stepU = 2.0*s/(T)sepU ;
00263 u1 = guessU-s ;
00264 u2 = guessU+s ;
00265 }
00266 else{
00267 stepU = s ;
00268 u1 = guessU ;
00269 u2 = guessU ;
00270 }
00271 if(sepV>0){
00272 stepV = 2.0*s/(T)sepV ;
00273 v1 = guessV-s ;
00274 v2 = guessV+s ;
00275 }
00276 else{
00277 stepV = s ;
00278 v1 = guessV ;
00279 v2 = guessV ;
00280 }
00281 while(d>error && niter<maxIter) {
00282 if(u1<um)
00283 u1=um;
00284 if(u2>uM)
00285 u2 = uM ;
00286 if(v1<vm)
00287 v1 = vm ;
00288 if(v2>vM)
00289 v2 = vM ;
00290 T u,v ;
00291 d2 = d1 ;
00292 for(u=u1;u<=u2;u+=stepU)
00293 for(v=v1;v<=v2;v+=stepV){
00294 p2 = pointAt(u,v) ;
00295 d1 = to2power_xy(p-p2) ;
00296 if(d1<d){
00297 d = d1 ;
00298 dz = to2power(p.z()-p2.z()) ;
00299 guessU = u ;
00300 guessV = v ;
00301 }
00302 }
00303 if(d-d2==0) niter = maxIter ;
00304 if(stepU<dU) niter = maxIter ;
00305 if(stepV<dU) niter = maxIter ;
00306 s = stepU*0.55 ;
00307 u1 = guessU - s ;
00308 u2 = guessU + s ;
00309 s = stepV*0.55 ;
00310 v1 = guessV - s ;
00311 v2 = guessV + s ;
00312 stepU *= 0.5 ;
00313 stepV *= 0.5 ;
00314 ++niter;
00315 }
00316 return dz ;
00317
00318 }
00319
00343 template <class T, int N>
00344 int ParaSurface<T,N>::writeVRML(const char* filename,const Color& color,int Nu,int Nv, T uS,T uE,T vS, T vE) const {
00345 ofstream fout(filename) ;
00346
00347 if(!fout)
00348 return 0 ;
00349 return writeVRML(fout,color,Nu,Nv,uS,uE,vS,vE) ;
00350 }
00351
00352
00376 template <class T, int N>
00377 int ParaSurface<T,N>::writeVRML(ostream &fout,const Color& color,int Nu,int Nv, T uS,T uE,T vS, T vE) const {
00378
00379 fout << "#VRML V1.0 ascii\n" ;
00380 fout << "# Generated by Phil's NURBS library\n" ;
00381 fout << "\nSeparator {\n" << "\tMaterialBinding { value PER_VERTEX_INDEXED }\n" ;
00382 fout << "\tMaterial{\n\t\tambientColor 0.25 0.25 0.25\n\t\tdiffuseColor " << float(color.r/255.0) << ' ' << float(color.g/255.0) << ' ' << float(color.b/255.0) << "\n\t}\n" ;
00383 fout << "\tCoordinate3 {\n" ;
00384 fout << "\t\tpoint [\n" ;
00385
00386 T u,v,du,dv ;
00387
00388 if(Nu<=1)
00389 Nu = 2 ;
00390 if(Nv<=1)
00391 Nv = 2 ;
00392
00393 u = uS ;
00394 v = vS ;
00395 du = (uE-uS)/(T)(Nu-1) ;
00396 dv = (vE-vS)/(T)(Nv-1) ;
00397
00398 int i,j ;
00399
00400
00401 for(i=0;i<Nu;++i){
00402 v = vS ;
00403 for(j=0 ;j<Nv;++j){
00404 Point_nD<T,N> p ;
00405 p = pointAt(u,v) ;
00406 fout << "\t\t\t" << p.x() << ' ' << p.y() << ' ' << p.z() << ",\n" ;
00407 v += dv ;
00408 }
00409 u += du ;
00410 }
00411
00412 fout << "\t\t]\n" ;
00413 fout << "\t}\n" ;
00414
00415 fout << "\tIndexedFaceSet{\n" ;
00416 fout << "\t\tcoordIndex[\n" ;
00417
00418 for(i=0;i<Nu-1;++i){
00419 for(j=0;j<Nv-1;++j) {
00420 fout << "\t\t\t" << i*Nv+j << ", " << i*Nv+j+1 << ", " << (i+1)*Nv+j << ", -1,\n";
00421 fout << "\t\t\t" << i*Nv+j+1 << ", " << (i+1)*Nv+j+1<< ", " << (i+1)*Nv+j << ", -1,\n";
00422 }
00423 }
00424 fout << "\t\t]\n" ;
00425 fout << "\t}\n" ;
00426
00427 fout << "}\n" ;
00428
00429 return 1 ;
00430 }
00431
00432 template <class T>
00433 inline T compare(int findMin, T a, T b){
00434 if(findMin)
00435 return minimum(a,b) ;
00436 return maximum(a,b) ;
00437 }
00438
00439
00440 #ifndef INCLUDE_TEMPLATE_SOURCE
00441 template <class T,int N>
00442 inline T coordValue(CoordinateType coord, const Point_nD<T,N>& p){
00443 switch(coord){
00444 case coordX: return p.x() ; break ;
00445 case coordY: return p.y() ; break ;
00446 case coordZ: return p.z() ; break ;
00447 }
00448 return 0.0 ;
00449 }
00450 #endif
00451
00478 template <class T, int N>
00479 T ParaSurface<T,N>::extremum(int findMin, CoordinateType coord, T minDu, int sepU, int sepV, int maxIter, T um, T uM, T vm, T vM) const {
00480 T c,du,dv,d1,d2,result,guessU,guessV ;
00481 T minDv = minDu ;
00482 Point_nD<T,N> p2 ;
00483
00484 guessU = 0 ;
00485 guessV = 0 ;
00486
00487
00488
00489
00490 p2 = pointAt(um,vm) ;
00491 c = coordValue(coord,p2) ;
00492 p2 = pointAt(um,vM) ;
00493 c = compare(findMin,c,coordValue(coord,p2)) ;
00494 p2 = pointAt(uM,vm) ;
00495 c = compare(findMin,c,coordValue(coord,p2)) ;
00496 p2 = pointAt(uM,vM) ;
00497 c = compare(findMin,c,coordValue(coord,p2)) ;
00498 result = c ;
00499 du = minDu*10.0 ;
00500 dv = minDv*10.0 ;
00501 d2 = d1 = 0 ;
00502 int niter = 0 ;
00503 T u1,u2 ;
00504 T v1,v2 ;
00505 T stepU,stepV ;
00506 T s ;
00507 s = uM - um ;
00508 stepU = s/(T)(sepU+1) ;
00509 stepV = s/(T)(sepV+1) ;
00510 u1 = um ;
00511 u2 = uM ;
00512 v1 = vm ;
00513 v2 = vM ;
00514 while((du>minDu || dv>minDv) && niter<maxIter) {
00515 if(u1<um)
00516 u1=um;
00517 if(u2>uM)
00518 u2 = uM ;
00519 if(v1<vm)
00520 v1 = vm ;
00521 if(v2>vM)
00522 v2 = vM ;
00523 T u,v ;
00524 d2 = c ;
00525 du = guessU ;
00526 dv = guessV ;
00527 for(u=u1;u<=u2;u+=stepU)
00528 for(v=v1;v<=v2;v+=stepV){
00529 p2 = pointAt(u,v) ;
00530 if(findMin){
00531 d1 = minimum(c,coordValue(coord,p2)) ;
00532 if(d1<c){
00533 c = d1 ;
00534 guessU = u ;
00535 guessV = v ;
00536 result = d1 ;
00537 }
00538 }
00539 else{
00540 d1 = maximum(c,coordValue(coord,p2)) ;
00541 if(d1>c){
00542 c = d1 ;
00543 guessU = u ;
00544 guessV = v ;
00545 result = d1 ;
00546 }
00547 }
00548 }
00549 s /= 2.0 ;
00550 u1 = guessU - s ;
00551 u2 = guessU + s ;
00552 v1 = guessV - s ;
00553 v2 = guessV + s ;
00554 stepU = 2.0*s/(T)sepU ;
00555 stepV = 2.0*s/(T)sepV ;
00556 if((c-d2)==0.0) niter = maxIter ;
00557 if(stepU<minDu) niter = maxIter ;
00558 if(stepV<minDv) niter = maxIter ;
00559 du = absolute(guessU-du) ;
00560 dv = absolute(guessV-dv) ;
00561 niter++;
00562 }
00563 return result ;
00564 }
00565
00613 template <class T, int N>
00614 int ParaSurface<T,N>::projectOn(const Point_nD<T,N>& p, T& u, T& v, int maxI, const T um, const T uM, const T vm, const T vM) const {
00615 int i = 0 ;
00616 Point_nD<T,N> xu,xv,x,t ;
00617 Matrix< Point_nD<T,N> >ders ;
00618 Matrix_DOUBLE A(6,2) ;
00619 Matrix_DOUBLE B(6,1) ;
00620 Matrix_DOUBLE X(2,1) ;
00621
00622
00623
00624 while(i < maxI){
00625
00626 boundTo(u,um,uM);
00627 boundTo(v,vm,vM);
00628
00629
00630 deriveAt(u,v,1,ders) ;
00631 xu = ders(1,0) ;
00632 xv = ders(0,1) ;
00633 x = ders(0,0) ;
00634
00635 t = xu*xu ;
00636 A(0,0) = t.x() ;
00637 A(1,0) = t.y() ;
00638 A(2,0) = t.z() ;
00639
00640 t = xu*xv ;
00641 A(0,1) = t.x() ;
00642 A(1,1) = t.y() ;
00643 A(2,1) = t.z() ;
00644
00645 t = xv*xu ;
00646 A(3,0) = t.x() ;
00647 A(4,0) = t.y() ;
00648 A(5,0) = t.z() ;
00649
00650 t = xv*xv ;
00651 A(3,1) = t.x() ;
00652 A(4,1) = t.y() ;
00653 A(5,1) = t.z() ;
00654
00655 t = (p-x)*xu ;
00656 B(0,0) = t.x() ;
00657 B(1,0) = t.y() ;
00658 B(2,0) = t.z() ;
00659
00660 t = (p-x)*xv ;
00661 B(3,0) = t.x() ;
00662 B(4,0) = t.y() ;
00663 B(5,0) = t.z() ;
00664
00665
00666 SVDMatrix<double> svd(A) ;
00667 if(!svd.solve(B,X))
00668 return 0 ;
00669
00670
00671
00672 if(T(X(0,0)) == T(0) && (T)X(1,0) == T(0)){
00673
00674 return 1 ;
00675 }
00676
00677 u += (T)X(0,0) ;
00678 v += (T)X(1,0) ;
00679 ++i ;
00680 }
00681
00682 return 0 ;
00683 }
00684
00708 template <class T, int N>
00709 int ParaSurface<T,N>::intersectWith(const ParaSurface<T,N> &S, Point_nD<T,N>& p, T& u, T& v, T& s, T& t, int maxI, T um, T uM, T vm, T vM) const{
00710 Point_nD<T,N> xu,xv,x1,x2,tmp,n1,n2,n12 ;
00711
00712 Matrix< Point_nD<T,N> > ders ;
00713 Matrix_DOUBLE A(6,2) ;
00714 Matrix_DOUBLE B(6,1) ;
00715 Matrix_DOUBLE X(2,1) ;
00716 Matrix_DOUBLE A2(3,3) ;
00717 Matrix_DOUBLE B2(3,1) ;
00718 Matrix_DOUBLE X2(3,1) ;
00719
00720 int done = 0 ;
00721 int i = 0 ;
00722 while(i<maxI){
00723
00724 boundTo(u,um,uM) ;
00725 boundTo(v,vm,vM) ;
00726 boundTo(s,um,uM) ;
00727 boundTo(t,vm,vM) ;
00728
00729 deriveAt(u,v,1,ders) ;
00730 xu = ders(1,0) ;
00731 xv = ders(0,1) ;
00732 x1 = ders(0,0) ;
00733 n1 = crossProduct(xu,xv) ;
00734
00735 tmp = xu*xu ;
00736 A(0,0) = tmp.x() ;
00737 A(1,0) = tmp.y() ;
00738 A(2,0) = tmp.z() ;
00739
00740 tmp = xu*xv ;
00741 A(0,1) = tmp.x() ;
00742 A(1,1) = tmp.y() ;
00743 A(2,1) = tmp.z() ;
00744
00745 tmp = xv*xu ;
00746 A(3,0) = tmp.x() ;
00747 A(4,0) = tmp.y() ;
00748 A(5,0) = tmp.z() ;
00749
00750 tmp = xv*xv ;
00751 A(3,1) = tmp.x() ;
00752 A(4,1) = tmp.y() ;
00753 A(5,1) = tmp.z() ;
00754
00755 tmp = (p-x1)*xu ;
00756 B(0,0) = tmp.x() ;
00757 B(1,0) = tmp.y() ;
00758 B(2,0) = tmp.z() ;
00759
00760 tmp = (p-x1)*xv ;
00761 B(3,0) = tmp.x() ;
00762 B(4,0) = tmp.y() ;
00763 B(5,0) = tmp.z() ;
00764
00765
00766 SVDMatrix<double> svd(A) ;
00767 if(!svd.solve(B,X))
00768 return 0 ;
00769
00770
00771
00772 if(T(X(0,0)) == T(0) && (T)X(1,0) == T(0)){
00773 done = 1 ;
00774
00775 }
00776
00777 u += (T)X(0,0) ;
00778 v += (T)X(1,0) ;
00779
00780
00781
00782 S.deriveAt(s,t,1,ders) ;
00783 xu = ders(1,0) ;
00784 xv = ders(0,1) ;
00785 x2 = ders(0,0) ;
00786 n2 = crossProduct(xu,xv) ;
00787
00788 tmp = xu*xu ;
00789 A(0,0) = tmp.x() ;
00790 A(1,0) = tmp.y() ;
00791 A(2,0) = tmp.z() ;
00792
00793 tmp = xu*xv ;
00794 A(0,1) = tmp.x() ;
00795 A(1,1) = tmp.y() ;
00796 A(2,1) = tmp.z() ;
00797
00798 tmp = xv*xu ;
00799 A(3,0) = tmp.x() ;
00800 A(4,0) = tmp.y() ;
00801 A(5,0) = tmp.z() ;
00802
00803 tmp = xv*xv ;
00804 A(3,1) = tmp.x() ;
00805 A(4,1) = tmp.y() ;
00806 A(5,1) = tmp.z() ;
00807
00808 tmp = (p-x2)*xu ;
00809 B(0,0) = tmp.x() ;
00810 B(1,0) = tmp.y() ;
00811 B(2,0) = tmp.z() ;
00812
00813 tmp = (p-x2)*xv ;
00814 B(3,0) = tmp.x() ;
00815 B(4,0) = tmp.y() ;
00816 B(5,0) = tmp.z() ;
00817
00818
00819 svd.decompose(A) ;
00820 if(!svd.solve(B,X))
00821 return 0 ;
00822
00823
00824
00825 if(T(X(0,0)) == T(0) && (T)X(1,0) == T(0)){
00826 if(done) {
00827 cerr << i << endl ;
00828 return 1 ;
00829 }
00830 done = 0 ;
00831 }
00832
00833 s += (T)X(0,0) ;
00834 t += (T)X(1,0) ;
00835
00836
00837
00838
00839 if(i>0){
00840 A2(0,0) = n1.x() ;
00841 A2(0,1) = n1.y() ;
00842 A2(0,2) = n1.z() ;
00843 A2(1,0) = n2.x() ;
00844 A2(1,1) = n2.y() ;
00845 A2(1,2) = n2.z() ;
00846 n12 = crossProduct(n1,n2) ;
00847 A2(2,0) = n12.x() ;
00848 A2(2,1) = n12.y() ;
00849 A2(2,2) = n12.z() ;
00850
00851 B2(0,0) = x1*n1 ;
00852 B2(1,0) = x2*n2 ;
00853 const T alpha = 0.3 ;
00854 const T beta = 0.3 ;
00855 const T lambda = 0.4 ;
00856 B2(2,0) = (alpha*x1 + beta *x2 + lambda * p)*n12 ;
00857
00858 SVDMatrix<double> svd3(A2) ;
00859 if(!svd3.solve(B2,X2))
00860 return 0 ;
00861
00862
00863 p.x() = X2(0,0) ;
00864 p.y() = X2(1,0) ;
00865 p.z() = X2(2,0) ;
00866 }
00867
00868 ++i ;
00869 }
00870
00871 return 1 ;
00872 }
00873
00874
00891 template <class T, int N>
00892 int ParaSurface<T,N>::intersectWith(const ParaSurface<T,N> &S, InterPoint<T,N> &iter, int maxI, T um, T uM, T vm, T vM) const{
00893 Point_nD<T,N> xu,xv,x1,x2,tmp,n1,n2,n12 ;
00894
00895 Matrix< Point_nD<T,N> > ders ;
00896 Matrix_DOUBLE A(6,2) ;
00897 Matrix_DOUBLE B(6,1) ;
00898 Matrix_DOUBLE X(2,1) ;
00899 Matrix_DOUBLE A2(3,3) ;
00900 Matrix_DOUBLE B2(3,1) ;
00901 Matrix_DOUBLE X2(3,1) ;
00902
00903 int done = 0 ;
00904 int i = 0 ;
00905
00906 Point_nD<T,N> &p = iter.point ;
00907 T &u = iter.paramA.u ;
00908 T &v = iter.paramA.v ;
00909 T &s = iter.paramB.u ;
00910 T &t = iter.paramB.v ;
00911
00912 while(i<maxI){
00913
00914 boundTo(u,um,uM) ;
00915 boundTo(v,vm,vM) ;
00916 boundTo(s,um,uM) ;
00917 boundTo(t,vm,vM) ;
00918
00919 deriveAt(u,v,1,ders) ;
00920 xu = ders(1,0) ;
00921 xv = ders(0,1) ;
00922 x1 = ders(0,0) ;
00923 n1 = crossProduct(xu,xv) ;
00924
00925 tmp = xu*xu ;
00926 A(0,0) = tmp.x() ;
00927 A(1,0) = tmp.y() ;
00928 A(2,0) = tmp.z() ;
00929
00930 tmp = xu*xv ;
00931 A(0,1) = tmp.x() ;
00932 A(1,1) = tmp.y() ;
00933 A(2,1) = tmp.z() ;
00934
00935 tmp = xv*xu ;
00936 A(3,0) = tmp.x() ;
00937 A(4,0) = tmp.y() ;
00938 A(5,0) = tmp.z() ;
00939
00940 tmp = xv*xv ;
00941 A(3,1) = tmp.x() ;
00942 A(4,1) = tmp.y() ;
00943 A(5,1) = tmp.z() ;
00944
00945 tmp = (p-x1)*xu ;
00946 B(0,0) = tmp.x() ;
00947 B(1,0) = tmp.y() ;
00948 B(2,0) = tmp.z() ;
00949
00950 tmp = (p-x1)*xv ;
00951 B(3,0) = tmp.x() ;
00952 B(4,0) = tmp.y() ;
00953 B(5,0) = tmp.z() ;
00954
00955
00956 SVDMatrix<double> svd(A) ;
00957 if(!svd.solve(B,X)){
00958 iter.tangent = crossProduct(n1,n2).unitLength() ;
00959 return 0 ;
00960 }
00961
00962
00963
00964 if(T(X(0,0)) == T(0) && (T)X(1,0) == T(0)){
00965 done = 1 ;
00966
00967 }
00968
00969 u += (T)X(0,0) ;
00970 v += (T)X(1,0) ;
00971
00972
00973
00974 S.deriveAt(s,t,1,ders) ;
00975 xu = ders(1,0) ;
00976 xv = ders(0,1) ;
00977 x2 = ders(0,0) ;
00978 n2 = crossProduct(xu,xv) ;
00979
00980 tmp = xu*xu ;
00981 A(0,0) = tmp.x() ;
00982 A(1,0) = tmp.y() ;
00983 A(2,0) = tmp.z() ;
00984
00985 tmp = xu*xv ;
00986 A(0,1) = tmp.x() ;
00987 A(1,1) = tmp.y() ;
00988 A(2,1) = tmp.z() ;
00989
00990 tmp = xv*xu ;
00991 A(3,0) = tmp.x() ;
00992 A(4,0) = tmp.y() ;
00993 A(5,0) = tmp.z() ;
00994
00995 tmp = xv*xv ;
00996 A(3,1) = tmp.x() ;
00997 A(4,1) = tmp.y() ;
00998 A(5,1) = tmp.z() ;
00999
01000 tmp = (p-x2)*xu ;
01001 B(0,0) = tmp.x() ;
01002 B(1,0) = tmp.y() ;
01003 B(2,0) = tmp.z() ;
01004
01005 tmp = (p-x2)*xv ;
01006 B(3,0) = tmp.x() ;
01007 B(4,0) = tmp.y() ;
01008 B(5,0) = tmp.z() ;
01009
01010
01011 svd.decompose(A) ;
01012 if(!svd.solve(B,X)){
01013 iter.tangent = crossProduct(n1,n2).unitLength() ;
01014 return 0 ;
01015 }
01016
01017
01018
01019 if(T(X(0,0)) == T(0) && (T)X(1,0) == T(0)){
01020 if(done) {
01021 iter.tangent = crossProduct(n1,n2).unitLength() ;
01022 return 1 ;
01023 }
01024 done = 0 ;
01025 }
01026
01027 s += (T)X(0,0) ;
01028 t += (T)X(1,0) ;
01029
01030
01031
01032
01033 if(i>0){
01034 A2(0,0) = n1.x() ;
01035 A2(0,1) = n1.y() ;
01036 A2(0,2) = n1.z() ;
01037 A2(1,0) = n2.x() ;
01038 A2(1,1) = n2.y() ;
01039 A2(1,2) = n2.z() ;
01040 n12 = crossProduct(n1,n2) ;
01041 A2(2,0) = n12.x() ;
01042 A2(2,1) = n12.y() ;
01043 A2(2,2) = n12.z() ;
01044
01045 B2(0,0) = x1*n1 ;
01046 B2(1,0) = x2*n2 ;
01047 const T alpha = 0.3 ;
01048 const T beta = 0.3 ;
01049 const T lambda = 0.4 ;
01050 B2(2,0) = (alpha*x1 + beta *x2 + lambda * p)*n12 ;
01051
01052 SVDMatrix<double> svd3(A2) ;
01053 if(!svd3.solve(B2,X2)){
01054 iter.tangent = crossProduct(n1,n2).unitLength() ;
01055 return 0 ;
01056 }
01057
01058
01059 p.x() = X2(0,0) ;
01060 p.y() = X2(1,0) ;
01061 p.z() = X2(2,0) ;
01062 }
01063
01064 ++i ;
01065 }
01066
01067 iter.tangent = crossProduct(n1,n2).unitLength() ;
01068 return 1 ;
01069 }
01070
01071 template <class T, int N>
01072 inline int isNear(const SurfParam<T,N> &a, const SurfParam<T,N>& b, double tol=1e-5){
01073 double d2 = ((double)a.u-(double)b.u)*((double)a.u-(double)b.u);
01074 d2 += ((double)a.v-(double)b.v)*((double)a.v-(double)b.v) ;
01075 if(d2<tol*tol)
01076 return 1 ;
01077 return 0 ;
01078 }
01079
01080 template <class T, int N>
01081 inline int isNear(const InterPoint<T,N>& a, const InterPoint<T,N> &b){
01082 return isNear(a.paramA,b.paramA) || isNear(a.paramB,b.paramB) ;
01083 }
01084
01085 template <class T, int N>
01086 inline int onBoundary(const SurfParam<T,N>& a, T m = 0, T M=1){
01087 if(a.u<=m)
01088 return 1 ;
01089 if(a.u>=M)
01090 return 1 ;
01091 return 0 ;
01092 }
01093
01094 template <class T, int N>
01095 void intersectSurfaces(const ParaSurface<T,N> &surfA, const ParaSurface<T,N> &surfB, BasicList<InterPoint<T,N> > &points, int maxI, T um, T uM, T vm, T vM){
01096 points.reset() ;
01097
01098 Point_nD<T,N> p ;
01099
01100 p = surfA.pointAt(0.5,0.5) ;
01101
01102 InterPoint<T,N> I0,I,Ilast ;
01103
01104 I0.point = p ;
01105
01106 surfA.intersectWith(surfB,I0,maxI,um,uM,vm,vM) ;
01107
01108 I = Ilast = I0 ;
01109
01110 T d ;
01111
01112 d = 0.01 ;
01113 T direction = 1 ;
01114
01115 int closed = 0 ;
01116 int reach_bound = 0 ;
01117
01118 const T error = 0.1;
01119 const T up_bound = 1.5 ;
01120
01121 int n = 0 ;
01122
01123 while(1){
01124 points.add(I) ;
01125 I.point += direction*d*I.tangent ;
01126 surfA.intersectWith(surfB,I,maxI,um,uM,vm,vM) ;
01127 if(isNear(I0,I)){
01128 closed = 1 ;
01129 break ;
01130 }
01131 if(onBoundary(I.paramA) || onBoundary(I.paramB)){
01132 reach_bound =1 ;
01133 break ;
01134 }
01135 d = norm(Ilast.point-I.point) ;
01136 d *= error/acos(I.tangent*Ilast.tangent/up_bound) ;
01137 if(d<0.01)
01138 d = 0.01 ;
01139 if(d>100)
01140 break ;
01141 Ilast = I ;
01142 cout << I.point << "\t" << I.paramA.u << "," << I.paramA.v << ":" << I.paramB.u << "," << I.paramB.v << "\t" << I.tangent << "|" << d << endl ;
01143 ++n ;
01144 if(n>100)
01145 break ;
01146 }
01147 if(reach_bound){
01148
01149 direction *= -1 ;
01150 I = Ilast = I0 ;
01151 n = 0 ;
01152 while(1){
01153 points.add(I) ;
01154 I.point += direction*d*I.tangent ;
01155 surfA.intersectWith(surfB,I,maxI,um,uM,vm,vM) ;
01156 if(isNear(I0,I)){
01157 closed = 1 ;
01158 break ;
01159 }
01160 if(onBoundary(I.paramA) || onBoundary(I.paramB)){
01161 reach_bound =1 ;
01162 break ;
01163 }
01164 d = norm(Ilast.point-I.point) ;
01165 d *= error/acos(I.tangent*Ilast.tangent/up_bound) ;
01166 if(d<0.01)
01167 d = 0.01 ;
01168 if(d>100)
01169 break ;
01170 Ilast = I ;
01171 cout << I.point << "\t" << I.paramA.u << "," << I.paramA.v << ":" << I.paramB.u << "," << I.paramB.v << "\t" << I.tangent << "|" << d << endl ;
01172 ++n ;
01173 if(n>100)
01174 break ;
01175 }
01176 }
01177 }
01178
01202 template <class T, int N>
01203 int ParaSurface<T,N>::writeVRML97(const char* filename,const Color& color,int Nu,int Nv, T uS,T uE,T vS, T vE) const {
01204 ofstream fout(filename) ;
01205
01206 if(!fout)
01207 return 0 ;
01208 return writeVRML97(fout,color,Nu,Nv,uS,uE,vS,vE) ;
01209 }
01210
01211
01235 template <class T, int N>
01236 int ParaSurface<T,N>::writeVRML97(ostream &fout,const Color& color,int Nu,int Nv, T uS,T uE,T vS, T vE) const {
01237
01238 fout << "#VRML V2.0 utf8\n" ;
01239 fout << "# Generated by Phil's NURBS library\n" ;
01240 fout << "\nGroup {\n" ;
01241 fout << "\n children [\n" ;
01242
01243 fout << "\tDEF T Transform {\n";
01244 fout << "\t children [\n" ;
01245 fout << "\t\tShape {\n" ;
01246 fout << "\t\t appearance Appearance {\n" ;
01247 fout << "\t\t\tmaterial Material{ diffuseColor " << float(color.r/255.0) << ' ' << float(color.g/255.0) << ' ' << float(color.b/255.0) << " }\n" ;
01248 fout << "\t\t }\n" ;
01249 fout << "\t\t geometry IndexedFaceSet {\n" ;
01250 fout << "\t\t\tsolid FALSE\n" ;
01251 fout << "\t\t\tcoord Coordinate {\n" ;
01252 fout << "\t\t\t point [\n" ;
01253
01254 T u,v,du,dv ;
01255
01256 if(Nu<=1)
01257 Nu = 2 ;
01258 if(Nv<=1)
01259 Nv = 2 ;
01260
01261 u = uS ;
01262 v = vS ;
01263 du = (uE-uS)/(T)(Nu-1) ;
01264 dv = (vE-vS)/(T)(Nv-1) ;
01265
01266 int i,j ;
01267
01268 Point_nD<T,N> p_min = pointAt(u,v) ;
01269 Point_nD<T,N> p_max = pointAt(u,v) ;
01270
01271 for(i=0;i<Nu;++i){
01272 v = vS ;
01273 for(j=0 ;j<Nv;++j){
01274 Point_nD<T,N> p ;
01275 p = pointAt(u,v) ;
01276 fout << "\t\t\t\t" << p.x() << ' ' << p.y() << ' ' << p.z() << ",\n" ;
01277 v += dv ;
01278 if(p.x()<p_min.x()) p_min.x() = p.x();
01279 if(p.y()<p_min.y()) p_min.y() = p.y();
01280 if(p.z()<p_min.z()) p_min.z() = p.z();
01281 if(p.x()>p_max.x()) p_max.x() = p.x();
01282 if(p.y()>p_max.y()) p_max.y() = p.y();
01283 if(p.z()>p_max.z()) p_max.z() = p.z();
01284 }
01285 u += du ;
01286 }
01287
01288 fout << "\t\t\t ]\n" ;
01289 fout << "\t\t\t}\n" ;
01290
01291 fout << "\t\t\t coordIndex [\n" ;
01292
01293 for(i=0;i<Nu-1;++i){
01294 for(j=0;j<Nv-1;++j) {
01295 fout << "\t\t\t\t" << i*Nv+j << ", " << i*Nv+j+1 << ", " << (i+1)*Nv+j << ", -1,\n";
01296 fout << "\t\t\t\t" << i*Nv+j+1 << ", " << (i+1)*Nv+j+1<< ", " << (i+1)*Nv+j << ", -1,\n";
01297 }
01298 }
01299 fout << "\t\t\t ]\n" ;
01300 fout << "\t\t\t}\n" ;
01301 fout << "\t\t}\n" ;
01302 fout << "\t ]\n" ;
01303 fout << "\t}\n" ;
01304 fout << " ]\n" ;
01305 fout << "}\n" ;
01306
01307 Point_nD<T,N> p_mid((p_max.x()+p_min.x())/T(2),
01308 (p_max.y()+p_min.y())/T(2),
01309 (p_max.z()+p_min.z())/T(2));
01310
01311 T x_axis = p_max.x() - p_min.x() ;
01312 T y_axis = p_max.y() - p_min.y() ;
01313
01314 T axis = (x_axis< y_axis) ? y_axis : x_axis ;
01315 axis *= T(2) ;
01316
01317 fout << "Viewpoint {\n\t position " << p_mid.x() << ' ' << p_mid.y() << ' ' << p_max.z()+axis << "\n\t description \"top\"\n}\n" ;
01318
01319
01320 fout << "NavigationInfo { type \"EXAMINE\" }\n" ;
01321
01322 return 1 ;
01323 }
01324
01325
01326
01327
01328 }
01329
01330 #endif // #define PLIB_NURBS_SURFACE_SOURCE