IntersectionLink.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools
00003 //
00004 // GoTools module: Intersections, version 1.0
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //===========================================================================
00033 #ifndef _INTERSECTIONLINK_H
00034 #define _INTERSECTIONLINK_H
00035 
00036 
00037 #include "IntersectionPoint.h"
00038 #include "LinkType.h"
00039 #include <boost/shared_ptr.hpp>
00040 #include <fstream> // remove after debugging
00041 #include "LineCloud.h" // remove after debugging
00042 
00043 
00044 namespace Go {
00047 
00048 
00049 
00054 
00055 class IntersectionLink {
00056 public:
00058     IntersectionLink(IntersectionPoint* p1, 
00059                      IntersectionPoint* p2)
00060         : p1_(p1), p2_(p2), delimits_partial_coincidence_(false)
00061     { 
00062         ASSERT(p1_->getObj1() == p2->getObj1());
00063         ASSERT(p1_->getObj2() == p2->getObj2());
00064         for (int i = 0; i < 4; iso_[i++] = false);
00065     }
00066 
00069     void getIntersectionPoints(IntersectionPoint*& p1,
00070                                IntersectionPoint*& p2)
00071     {
00072         p1 = p1_;
00073         p2 = p2_;
00074     }
00075 
00078     void getIntersectionPoints(const IntersectionPoint*& p1,
00079                                const IntersectionPoint*& p2) const
00080     {
00081         p1 = p1_;
00082         p2 = p2_;
00083     }
00084 
00087     IntersectionPoint* getOtherPoint(const IntersectionPoint* p1)
00088     {
00089         return (p1 == p1_) ? p2_ : ((p1 == p2_) ? p1_ : 0);
00090     }
00091 
00093     bool isAttachedTo(const IntersectionPoint* ip)
00094     {
00095         return (ip == p1_) || (ip == p2_);
00096     }
00097 
00100     void copyMetaInformation(const IntersectionLink& rhs)
00101     {
00102         delimits_partial_coincidence_ = rhs.delimits_partial_coincidence_;
00103         for (int i = 0; i < 4; iso_[i] = rhs.iso_[i++]);
00104     }
00105 
00108     bool delimitsPAC() const 
00109     {
00110         return delimits_partial_coincidence_;
00111     }
00112 
00113     void setPAC(bool value) 
00114     {
00115         delimits_partial_coincidence_ = value;
00116     }
00117     
00118     void setIsoparametricIn(int dir, bool iso) 
00119     {
00120         ASSERT(dir >= 0 && dir < (p1_->numParams1() + p1_->numParams2()));
00121         iso_[dir] = iso;
00122         
00123         // debug purposes
00124         if (iso_[0] && iso_[1]) {
00125             //MESSAGE("Too many iso parametric directions");
00126 //          ASSERT(false); // a link cannot be isoparametric in both
00127 //                         // directions
00128         } 
00129         if (iso_[2] && iso_[3]) {
00130             //MESSAGE("Too many iso parametric directions");
00131 //          ASSERT(false);
00132         }
00133     }
00134 
00135     bool isIsoparametricIn(int dir)  const 
00136     {
00137         ASSERT(dir >= 0 && dir < numParams());
00138         return iso_[dir];
00139     }
00140 
00141     bool isIsoparametric() const 
00142     {
00143         int num_param = numParams();
00144         for (int i = 0; i < num_param; ++i) {
00145             if (iso_[i]) {
00146                 return true;
00147             }
00148         }
00149         return false;
00150     }
00151     
00152     int numParams() const 
00153     {
00154         return p1_->numParams1() + p1_->numParams2();
00155     }
00156 
00158     int crosses(const boost::shared_ptr<IntersectionLink>& link) const
00159         // 
00160         // Return value : 2 - crossing links
00161         //                1 - close links
00162         //                0 - distant links
00163     {
00164         // Define two algebraic functions, a*x + b*y - c = 0, for
00165         // 'this' and 'link', respectively. Check if the two points on
00166         // one link lies on each side of the other, and vice versa.
00167 
00168         int close = 0;
00169         const IntersectionPoint *p1, *p2, *q1, *q2;
00170         getIntersectionPoints(p1, p2);
00171         link->getIntersectionPoints(q1, q2);
00172 
00173         double aeps = p1->getTolerance()->getEpsge();
00174         double tol = 100.0*aeps;
00175 
00176         // Only implemented for two surfaces
00177         if (p1->numParams1() != 2 || p1->numParams2() != 2) {
00178             MESSAGE("IntersectionLink::crosses() is only implemented "
00179                     "for two surfaces.");
00180             return 0;
00181         }
00182 
00183         // If the two links share a point, they don't cross and is not classified
00184         // as close
00185         if (p1 == q1 || p1 == q2 || p2 == q1 || p2 == q2)
00186             return 0;
00187 
00188         // Don't consider links shorther than the tolerance
00189         if (p1->getPoint().dist(p2->getPoint()) < aeps ||
00190             q1->getPoint().dist(q2->getPoint()) < aeps)
00191             return 0;
00192 
00193         // Loop over first and second surface (i=0 or i=2)
00194         for (int i = 0; i < 4; i += 2) 
00195         {
00196             // The points belonging to link two lies on either side
00197             Point a = (i<2) ? p1->getPar1Point() : p1->getPar2Point();
00198             Point b = (i<2) ? p2->getPar1Point() : p2->getPar2Point();
00199             Point c = (i<2) ? q1->getPar1Point() : q1->getPar2Point();
00200             Point d = (i<2) ? q2->getPar1Point() : q2->getPar2Point();
00201             Point n1(-(b[1]-a[1]), b[0]-a[0]);
00202             Point n2(-(d[1]-c[1]), d[0]-c[0]);
00203             n1.normalize();
00204             n2.normalize();
00205             double s1 = (a - c)*n1;
00206             double s2 = (a - d)*n1;
00207             double s3 = (c - a)*n2;
00208             double s4 = (c - b)*n2;
00209             if (s1*s2 < 0.0 && s3*s4 < 0.0)
00210             {
00211                 return 2;
00212             }
00213             else if (fabs(s1) < tol || fabs(s2) < tol || fabs(s3) < tol ||
00214                      fabs(s4) < tol)
00215                 close++;
00216             // of the infinite line through the points belonging to link one
00217 /*          // First link */
00218 /*          double a0 = p1->getPar(i+1) - p2->getPar(i+1); */
00219 /*          double b0 = p2->getPar(i) - p1->getPar(i); */
00220 /*          double c0 = p1->getPar(i+1) * p2->getPar(i) */
00221 /*              - p1->getPar(i) * p2->getPar(i+1); */
00222 /*          double q1val = a0*q1->getPar(i) + b0*q1->getPar(i+1) - c0; */
00223 /*          double q2val = a0*q2->getPar(i) + b0*q2->getPar(i+1) - c0; */
00224 /*          bool q_on_each_side = (q1val > 0.0 && q2val < 0.0) */
00225 /*              || (q1val < 0.0 && q2val > 0.0); */
00226 /*          if (!q_on_each_side) */
00227 /*              continue; */
00228 /*          // Second link */
00229 /*          double a1 = q1->getPar(i+1) - q2->getPar(i+1); */
00230 /*          double b1 = q2->getPar(i) - q1->getPar(i); */
00231 /*          double c1 = q1->getPar(i+1) * q2->getPar(i) */
00232 /*              - q1->getPar(i) * q2->getPar(i+1); */
00233 /*          double p1val = a1*p1->getPar(i) + b1*p1->getPar(i+1) - c1; */
00234 /*          double p2val = a1*p2->getPar(i) + b1*p2->getPar(i+1) - c1; */
00235 /*          bool p_on_each_side = (p1val > 0.0 && p2val < 0.0) */
00236 /*              || (p1val < 0.0 && p2val > 0.0); */
00237 /*          if (p_on_each_side) { */
00238 /*              return true; */
00239 /*          } */
00240         }
00241 
00242         return (close == 2) ? 1 : 0;
00243     }
00244 
00247     const LinkType& linkType() const
00248     { return link_type_; }
00249 
00252     LinkType& linkType()
00253     { return link_type_; }
00254 
00256     void writeInfo() const
00257     {
00258         // Parameters
00259         p1_->writeParams(std::cout);
00260         std::cout << "  --  ";
00261         p2_->writeParams(std::cout);
00262         std::cout << std::endl << "\t";
00263 
00264         // Cosines. cos1 refers to the angle between the tangent in p1
00265         // and the vector from p1 to p2. Similarly with cos2.
00266         Point linkdir = p2_->getPoint() - p1_->getPoint();
00267         double len = linkdir.length();
00268         bool has_nonzero_link = (len != 0.0);
00269         if (has_nonzero_link) {
00270             linkdir.normalize();
00271             bool has_tangent;
00272             has_tangent
00273                 = (p1_->getSingularityType() == ORDINARY_POINT
00274                    || p1_->getSingularityType() == TANGENTIAL_POINT);
00275             if (has_tangent) {
00276                 Point tangent = p1_->getTangent();
00277                 tangent.normalize();
00278                 double cos = tangent * linkdir;
00279                 std::cout << "cos1 = ";
00280                 std::cout.width(std::cout.precision()+4);
00281                 std::cout << cos << "  ";
00282             }
00283             else {
00284                 std::cout << "cos1 = no tangent  ";
00285             } 
00286 
00287             has_tangent
00288                 = (p2_->getSingularityType() == ORDINARY_POINT
00289                    || p2_->getSingularityType() == TANGENTIAL_POINT);
00290             if (has_tangent) {
00291                 Point tangent = p2_->getTangent();
00292                 tangent.normalize();
00293                 double cos = -tangent * linkdir;
00294                 std::cout << "cos2 = ";
00295                 std::cout.width(std::cout.precision()+4);
00296                 std::cout << cos << "  ";
00297             }
00298             else {
00299                 std::cout << "cos2 = no tangent  ";
00300             }
00301         }
00302         else {
00303             std::cout << "link length = 0.0                    ";
00304         }
00305 
00306         // Link type
00307         std::cout << "type = ";
00308         std::cout.width(2);
00309         std::cout << link_type_;
00310         
00311         return;
00312     }
00313 
00314     void dumpToStream(std::ostream& os) // debug reasons
00315     {
00316         double data[12];
00317         Point tmp = p1_->getPoint1();
00318         std::copy(tmp.begin(), tmp.end(), data);
00319         tmp = p2_->getPoint1();
00320         std::copy(tmp.begin(), tmp.end(), data+3);
00321         tmp = p1_->getPoint2();
00322         std::copy(tmp.begin(), tmp.end(), data+6);
00323         tmp = p2_->getPoint2();
00324         std::copy(tmp.begin(), tmp.end(), data+9);
00325         LineCloud lc(data,2);
00326         lc.writeStandardHeader(os);
00327         lc.write(os);
00328     }
00329 
00330 private:
00331     // the IntersectionLink should not be able to change or delete the
00332     // pointers to the IntersectionPoints it refers to. Hence the
00333     // 'const' keyword.  (It will however be able to call non-const
00334     // member functions of p1 and p2, so we cannot declare them to
00335     // point to 'const'-objects).
00336     IntersectionPoint* const p1_;
00337     IntersectionPoint* const p2_;
00338     
00339     bool delimits_partial_coincidence_;
00340     bool iso_[4];  // confirmed isoparametric intersection curve in a
00341                    // parameter
00342 
00343     LinkType link_type_;
00344 
00345 };
00346 
00347 
00349 }; // end namespace Go
00350 
00351 
00352 #endif // _INTERSECTIONLINK_H
00353 
00354 

Generated on Fri Nov 23 12:24:33 2007 for GoTools Intersections Library by  doxygen 1.5.1