IntersectionPoint.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 _INTERSECTIONPOINT_H
00034 #define _INTERSECTIONPOINT_H
00035 
00036 
00037 #include "IntersectionPointUtils.h"
00038 #include "LinkType.h"
00039 #include "GeoTol.h"
00040 #include "SecondOrderProperties.h"
00041 #include <boost/shared_ptr.hpp>
00042 #include <vector>
00043 #include <map>
00044 
00045 
00046 namespace Go {
00049 
00050 
00051 
00052 class ParamObjectInt;
00053 class ParamGeomInt;
00054 class ParamSurface;
00055 class IntersectionLink;
00056 
00057 
00060 
00061 class IntersectionPoint {
00062 public:
00074     IntersectionPoint(const ParamObjectInt* obj1, 
00075                       const ParamObjectInt* obj2,
00076                       const boost::shared_ptr<GeoTol> epsge,                  
00077                       const double* obj1_params,
00078                       const double* obj2_params);
00079 
00099     IntersectionPoint(const ParamObjectInt* obj1,
00100                       const ParamObjectInt* obj2,
00101                       const boost::shared_ptr<IntersectionPoint> ip,
00102                       int missing_param);
00103 
00105     ~IntersectionPoint();
00106 
00108     IntersectionPoint() {} // create an undefined point which can be
00109                            // assigned or read() into.
00110     
00114     void write(std::ostream& os) const;
00115 
00119     // @@This function is for debugging.  Do not
00120     // try to do anything serious with it.  It must create 'new'
00121     // objects for its pointers, and thus causes memory leaks!
00122     void read(std::istream& is);
00123 
00126     void writeParams(std::ostream& os) const;
00127 
00130     void writeInfo() const;
00131 
00139     void replaceParameter(double *param);
00140     
00144     Point getPoint() const;
00145 
00149     Point getPoint1() const
00150     { return point1_; }
00151 
00155     Point getPoint2() const
00156     { return point2_; }
00157 
00170     void projectToParamPlanes(const Point& dir, 
00171                               Point& par_1_dir, Point& par_2_dir) const;
00172 
00181     bool hasUniqueTangentDirection() const; 
00182 
00192     bool tangentIsOriented() const;
00193 
00199     double getDist() const
00200     { return dist_; }
00201 
00204     const std::vector<double>& getPar() const
00205     { return par_; }
00206 
00211     double getPar(int idx) const
00212     { return par_[idx]; }
00213 
00217     const double* getPar1() const;
00218 
00222     const double* getPar2() const;
00223 
00226     Point getPar1Point() const;
00229     Point getPar2Point() const;
00230 
00232     int numParams1() const;
00233 
00235     int numParams2() const;
00236 
00249     Point getTangent(bool second_branch = false) const;
00250 
00264     Point getPar1Dir(bool second_branch = false) const;
00265 
00280     Point getPar2Dir(bool second_branch = false) const;
00281 
00283     const ParamObjectInt* getObj1() const
00284     { return obj1_; }
00285 
00287     const ParamObjectInt* getObj2() const
00288     { return obj2_; }
00289 
00295     double startParam(int pardir);
00296 
00302     double endParam(int pardir);
00303 
00307     bool pointIsSingular() const
00308     { return getSingularityType() != ORDINARY_POINT; }
00309 
00312     bool isNearSingular() const;
00313 
00320     double parameterTolerance(int pardir); // pardir == 0 || pardir == 1
00321 
00335     void fixTangentOrientation(bool flip); 
00336 
00344     void isBoundaryPoint(bool& first, bool& second) const;
00345 
00368     void tangentPointingInwards(bool& first, 
00369                                 bool& second,
00370                                 bool& first_along_boundary,
00371                                 bool& second_along_boundary) const;
00372 
00381     bool isConnectedTo(boost::shared_ptr<IntersectionPoint> p) const
00382     { return isConnectedTo(p.get()); }
00383 
00391     bool isConnectedTo(const IntersectionPoint* point) const;
00392 
00419     boost::shared_ptr<IntersectionLink>
00420     connectTo(IntersectionPoint *const point, 
00421               LinkType type,
00422               boost::shared_ptr<IntersectionLink> model_link
00423               = boost::shared_ptr<IntersectionLink>(),
00424               int added_parameter_dir = -1);
00425 
00452     boost::shared_ptr<IntersectionLink>
00453     connectTo(boost::shared_ptr<IntersectionPoint> point, 
00454               LinkType type,
00455               boost::shared_ptr<IntersectionLink> model_link
00456               = boost::shared_ptr<IntersectionLink>(),
00457               int added_parameter_dir = -1)
00458     { return connectTo(point.get(), type,
00459                        model_link, added_parameter_dir); }
00460 
00466     void disconnectFrom(IntersectionPoint* point);
00467     
00472     int numBranches() const;
00473 
00486     IntPtClassification getClassification(const ParamSurface *surf1, 
00487                                           const ParamSurface *surf2,
00488                                           int branch_num = 0) const;
00489 
00503     IntPtClassification getClassification(const ParamSurface *par_func,
00504                                           double C,
00505                                           int branch_num = 0) const;
00506 
00508     SingularityType getSingularityType() const;
00509 
00512     boost::shared_ptr<GeoTol> getTolerance() 
00513     { return epsge_; }
00514 
00517     boost::shared_ptr<const GeoTol> getTolerance() const
00518     { return epsge_; }
00519 
00523     boost::shared_ptr<IntersectionPoint> parentPoint()
00524     { return parent_point_; }
00525 
00530     void setParentPoint(boost::shared_ptr<IntersectionPoint> p)
00531     {
00532         //ASSERT(!parent_point_); // should only be used with orphans
00533         parent_point_ = p;
00534     }
00535 
00536     bool hasParentPoint()
00537         {
00538             return (parent_point_.get() != 0);
00539         }
00540 
00543     void flipObjects();
00544 
00566     double getInfluenceArea(int dir, bool forward, bool first_outside,
00567                             double aeps=0.0) const;
00568 
00585     int inInfluenceArea(int pardir, double par, bool first_outside) const;
00586 
00597     void shareInfluenceAreaWith(boost::shared_ptr<IntersectionPoint> other_pt,
00598                                 int pardir);
00599 
00600     // @@@ VSK. For the time being, but needs implementing when the
00601     // CachedInterval::inside is OK
00605     bool inInfluenceAreaBracket(int pardir, double parval)
00606     { return false; }
00607 
00614     boost::shared_ptr<IntersectionLink>
00615     getIntersectionLink(const IntersectionPoint* point);
00616     
00623     void getNeighbours(std::vector<IntersectionPoint*>& pnts) const;
00624 
00629     void getNeighbourLinks(std::vector<boost::
00630                            shared_ptr<IntersectionLink> >& links) const;
00631 
00635     int numNeighbours()const { return int(intersection_links_.size()); }
00636 
00649     template<class bool_iterator>
00650     void setDifferentiateFromLeft(bool_iterator it) const  
00651     {
00652         int n = numParams1() + numParams2();
00653         ASSERT(n == int(diff_from_left_.size()));
00654         for (int i = 0; i < n; ++i, ++it) {
00655             diff_from_left_[i] = g2_discontinuous_params_[i] && (*it);
00656         }
00657         int key = bool2int(diff_from_left_.begin(), diff_from_left_.end());
00658         cur_active_2nd_order_properties_ = &sec_order_properties_[key];
00659     }
00660 
00666     bool differentiatesFromLeft(int pardir) const
00667     {
00668         ASSERT(pardir >= 0 && pardir < numParams1() + numParams2());
00669         return diff_from_left_[pardir];
00670     }
00671 
00681     int hasIsoLinks(int* const iso_par_dirs) const;
00682 
00693     int commonIsoLinks(int* const iso_par_dirs) const;
00694 
00699     bool containsG2Discontinuity() const 
00700     {
00701         int ki;
00702         for (ki=0; ki < int(g2_discontinuous_params_.size()); ki++)
00703             if (g2_discontinuous_params_[ki])
00704                 return true;
00705         return false;
00706     }
00707 
00711     bool isDegenerate() const;
00712 
00718     bool isSamePoint(const IntersectionPoint* point) const;
00719 
00728     bool checkIntersectionPoint(IntPtInfo& int_pt_info) const;
00729 
00737     bool isInDomain(double* frompar, double* topar) const;
00738 
00741     static const double tangent_tol;
00742 
00743 private:
00744 
00745     // ----- Data members -----
00746 
00747     // NB: the IntersectionPoint has no ownership to the objects
00748     // pointed to by obj1_ and obj2_
00749     const ParamObjectInt* obj1_; // Object number one
00750     const ParamObjectInt* obj2_; // Object number two
00751 
00752     Point point1_; // Intersection point in space in object number one
00753     Point point2_; // Intersection point in space in object number two
00754     double dist_;  // Distance between the points in the two objects
00755 
00756     // Parameter values of this intersection point
00757     std::vector<double> par_;
00758 
00759     // If obj1_ or obj2_ has parents, then parent_point_ is the
00760     // corresponding intersection point
00761     boost::shared_ptr<IntersectionPoint> parent_point_;
00762 
00763     // Contains link objects to other IntersectionPoints. The links
00764     // are unique.
00765     std::vector<boost::shared_ptr<IntersectionLink> > intersection_links_;
00766     
00767     // Tolerance-related stuff
00768     boost::shared_ptr<GeoTol> epsge_;
00769 
00770     // Caching of influence area
00771     mutable std::vector<CachedInterval> cached_influence_area_forwards_;
00772     mutable std::vector<CachedInterval> cached_influence_area_backwards_;
00773 
00774     // Information (that might be) influenced by the second derivative
00775     // of the surface.
00776     std::vector<bool> g2_discontinuous_params_;
00777     mutable std::map<int, SecondOrderProperties> sec_order_properties_;
00778     mutable SecondOrderProperties* cur_active_2nd_order_properties_;
00779     mutable std::vector<bool> diff_from_left_;
00780 
00781     // ------ member functions -----
00782 
00783     void constructor_implementation(const ParamObjectInt* obj1, 
00784                                     const ParamObjectInt* obj2,
00785                                     boost::shared_ptr<GeoTol> epsge,
00786                                     const double* obj_1_params,
00787                                     const double* obj_2_params);
00788 
00789     inline bool tangent_2d_is_cached() const
00790     { return cur_active_2nd_order_properties_->tangent_2d_is_cached; }
00791 
00792     inline bool singularity_info_is_cached() const
00793     { return cur_active_2nd_order_properties_->singularity_info_is_cached; }
00794 
00795     // Expecting object(s) to be 2-parametric.
00796     void compute_parametrical_tangents() const; 
00797     // The two following function are called (only) by
00798     // compute_parametrical_tangents())
00799     void compute_surface_parametrical_tangents_safe() const;
00800     void compute_function_parametrical_tangents() const; 
00801 
00802     // Calculates the tangent at a discovered singular point, and
00803     // return the point's SingularityType
00804     SingularityType calculate_tangent_at_singular_point() const;
00805 
00806     // Check each parameter for a second order discontinuity in the
00807     // IntersectionPoint
00808     //boost::shared_ptr<ParamObjectInt> obj2,
00809     static std::vector<bool> 
00810     detect_2nd_order_discontinuities(const ParamObjectInt* o1,
00811                                      const ParamObjectInt* o2,
00812                                      const boost::shared_ptr<GeoTol> gtol,
00813                                      const double* obj1_par,
00814                                      const double* obj2_par);
00815 
00816     void calculate_singularity_type() const;
00817     void calculate_singularity_type_function() const;
00818     void calculate_singularity_type_surface() const; // Assuming space is 3-d
00819     void calculate_singularity_type_curves() const ;
00820     void calculate_singularity_type_point() const;
00821     void calculate_singularity_type_curve_surface() const;
00822 
00823     static double determinant(const Point&, const Point&, const Point&);
00824     
00825     // We suppose that 'T' lies in the plane spanned by 'b1' and 'b2'.
00826     // We want to calculate the coefficients in order to express 'T'
00827     // as a linear combination of 'b1' and 'b2'.
00828 
00829     // Calculate the vector 'T', supposedly in the linear span of 'b1'
00830     // and 'b2', as a linear combination of the two.  The appropriate
00831     // coefficients are returned in 'b1_coef' and 'b2_coef'.  If 'T'
00832     // is _not_ in the plane, the projected vector is used.
00833     static void decompose(const Point& T, 
00834                           const Point& b1, 
00835                           const Point& b2, 
00836                           double& b1_coef,
00837                           double& b2_coef);
00838 
00839     // Project a vector to the tangent space of a geometric object,
00840     // and find the parametric direction in the object's parameter
00841     // space that correspond to this projection.  'dir' is the vector
00842     // to be projected.  The object is given by 'go', and the
00843     // parametrization for the point where the tangent space is
00844     // defined, is given by 'par'.  Whether the tangent space should
00845     // be computed used derivation "from left" or "from right" in each
00846     // parameter direction is dictated by 'from_left'.  The resulting
00847     // direction in parametric space is returned by 'par_dir'.
00848     static void proj_2_pplane(const Point& dir, 
00849                               const double* par,
00850                               std::vector<bool>::const_iterator from_left,
00851                               const ParamGeomInt* go, 
00852                               Point& par_dir);
00853 
00854     // Takes a range of bools and converts them to an int. The
00855     // resulting int has the binary representation that corresponds to
00856     // the range of bools.
00857     template<class iterator>
00858     static int bool2int(iterator begin_range, iterator end_range)
00859     {
00860         int result = 0;
00861         for (int pos = 0; begin_range != end_range; ++pos, ++begin_range) {
00862             // If the bool at the current position is true, then set the
00863             // bit at position 'pos' from the right in integer 'result'
00864             if (*begin_range) {
00865                 result |= (1 << pos); 
00866             }
00867         }
00868         return result;
00869     }
00870     
00871     // Takes an int and converts it to a range of bools. The resulting
00872     // bools correspond to the binary representation of the int.
00873     template<class iterator>
00874     static void int2bool(int number, iterator cur_pos, iterator end_range)
00875     {
00876         for (int pos = 0; cur_pos != end_range; ++pos, ++cur_pos) {
00877             // Set the bool at the current position to true if 'number'
00878             // has the bit at position 'pos' from the right turned on
00879             *cur_pos = number & (1 << pos);
00880         }
00881     }
00882 
00883     std::map<int, SecondOrderProperties> 
00884     generate_2nd_order_property_map(const std::vector<bool>& disc_params);
00885 
00886     inline bool exactly_on_point(int pardir, double par) const
00887     { return (fabs(par_[pardir] - par) < epsge_->getRelParRes()); }
00888 
00889     // Should be called whenever the IntersectionPoint is changed
00890     void clearCache() const
00891     {
00892         std::map<int, SecondOrderProperties>::iterator it;
00893         for (it = sec_order_properties_.begin();
00894              it != sec_order_properties_.end(); ++it) {
00895             (it->second).clear();
00896         }
00897         cached_influence_area_forwards_
00898             = cached_influence_area_backwards_
00899             = std::vector<CachedInterval>(par_.size());
00900         diff_from_left_ = std::vector<bool>(par_.size(), false);
00901         cur_active_2nd_order_properties_ = &sec_order_properties_[0];
00902     }
00903 
00904 };
00905 
00906 
00908 }; // namespace Go
00909 
00910 
00911 #endif  // _INTERSECTIONPOINT_H
00912 

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