function_objects.h

来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 2,317 行 · 第 1/5 页

H
2,317
字号
// Copyright (c) 1999-2004  Utrecht University (The Netherlands),// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg// (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),// and Tel-Aviv University (Israel).  All rights reserved.//// This file is part of CGAL (www.cgal.org); you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public License as// published by the Free Software Foundation; version 2.1 of the License.// See the file LICENSE.LGPL distributed with CGAL.//// Licensees holding a valid commercial license may use this file in// accordance with the commercial license agreement provided with the software.//// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.//// $Source: /CVSROOT/CGAL/Packages/H2/include/CGAL/Homogeneous/function_objects.h,v $// $Revision: 1.40 $ $Date: 2004/08/11 14:37:09 $// $Name:  $//// Author(s)     : Stefan Schirra, Sylvain Pion, Michael Hoffmann#ifndef CGAL_HOMOGENEOUS_FUNCTION_OBJECTS_H#define CGAL_HOMOGENEOUS_FUNCTION_OBJECTS_H#include <CGAL/Kernel/function_objects.h>#include <CGAL/Cartesian/function_objects.h>CGAL_BEGIN_NAMESPACEnamespace HomogeneousKernelFunctors {  using namespace CommonKernelFunctors;  // For lazyness...  using CartesianKernelFunctors::Are_parallel_2;  using CartesianKernelFunctors::Are_parallel_3;  using CartesianKernelFunctors::Compute_squared_area_3;  using CartesianKernelFunctors::Collinear_3;  using CartesianKernelFunctors::Construct_line_3;  template <typename K>  class Angle_2  {    typedef typename K::Point_2             Point_2;    typedef typename K::Construct_vector_2  Construct_vector_2;    Construct_vector_2 c;  public:    typedef Angle            result_type;    typedef Arity_tag< 3 >   Arity;      Angle_2() {}    Angle_2(const Construct_vector_2& c_) : c(c_) {}    Angle    operator()(const Point_2& p, const Point_2& q, const Point_2& r) const    { return (Angle) CGAL_NTS sign(c(q,p) * c(q,r)); }     // FIXME: scalar product  };  template <typename K>  class Angle_3  {    typedef typename K::Point_3             Point_3;    typedef typename K::Construct_vector_3  Construct_vector_3;    Construct_vector_3 c;  public:    typedef Angle            result_type;    typedef Arity_tag< 3 >   Arity;    Angle_3() {}    Angle_3(const Construct_vector_3& c_) : c(c_) {}    Angle    operator()(const Point_3& p, const Point_3& q, const Point_3& r) const    { return (Angle) CGAL_NTS sign(c(q,p) * c(q,r)); }     // FIXME: scalar product  };  template <typename K>  class Bounded_side_3  {    typedef typename K::RT              RT;    typedef typename K::Point_3         Point_3;    typedef typename K::Vector_3        Vector_3;    typedef typename K::Sphere_3        Sphere_3;    typedef typename K::Tetrahedron_3   Tetrahedron_3;    typedef typename K::Iso_cuboid_3    Iso_cuboid_3;  public:    typedef Bounded_side     result_type;    typedef Arity_tag< 2 >   Arity;    Bounded_side    operator()( const Sphere_3& s, const Point_3& p) const    { return s.bounded_side(p); }    Bounded_side    operator()( const Tetrahedron_3& t, const Point_3& p) const    {      RT alpha;      RT beta ;      RT gamma;      Vector_3 v1 = t.vertex(1)-t.vertex(0);      Vector_3 v2 = t.vertex(2)-t.vertex(0);      Vector_3 v3 = t.vertex(3)-t.vertex(0);      Vector_3 vp =   p     - t.vertex(0);      // want to solve  alpha*v1 + beta*v2 + gamma*v3 == vp      // let vi' == vi*vi.hw()      // we solve alpha'*v1' + beta'*v2' + gamma'*v3' == vp' / vp.hw()      //          muliplied by vp.hw()      // then we have  alpha = alpha'*v1.hw() / vp.hw()      // and           beta  = beta' *v2.hw() / vp.hw()      // and           gamma = gamma'*v3.hw() / vp.hw()      RT v1x = v1.hx();      RT v1y = v1.hy();      RT v1z = v1.hz();      RT v2x = v2.hx();      RT v2y = v2.hy();      RT v2z = v2.hz();      RT v3x = v3.hx();      RT v3y = v3.hy();      RT v3z = v3.hz();      RT vpx = vp.hx();      RT vpy = vp.hy();      RT vpz = vp.hz();      alpha = det3x3_by_formula( vpx, v2x, v3x,                                 vpy, v2y, v3y,                                 vpz, v2z, v3z );      beta  = det3x3_by_formula( v1x, vpx, v3x,                                 v1y, vpy, v3y,                                 v1z, vpz, v3z );      gamma = det3x3_by_formula( v1x, v2x, vpx,                                 v1y, v2y, vpy,                                 v1z, v2z, vpz );      RT det= det3x3_by_formula( v1x, v2x, v3x,                                 v1y, v2y, v3y,                                 v1z, v2z, v3z );      CGAL_kernel_assertion( det != 0 );      if (det < 0 )      {          alpha = - alpha;          beta  = - beta ;          gamma = - gamma;          det   = - det  ;      }      bool t1 = ( alpha < 0 );      bool t2 = ( beta  < 0 );      bool t3 = ( gamma < 0 );            // t1 || t2 || t3 == not contained in cone      RT lhs = alpha*v1.hw() + beta*v2.hw() + gamma*v3.hw();      RT rhs = det * vp.hw();      bool t4 = ( lhs > rhs );            // alpha + beta + gamma > 1 ?      bool t5 = ( lhs < rhs );            // alpha + beta + gamma < 1 ?      bool t6 = ( (alpha > 0) && (beta > 0) && (gamma > 0) );      if ( t1 || t2 || t3 || t4 )      {          return ON_UNBOUNDED_SIDE;      }      return (t5 && t6) ? ON_BOUNDED_SIDE : ON_BOUNDARY;    }    Bounded_side    operator()( const Iso_cuboid_3& c, const Point_3& p) const    { return c.bounded_side(p); }  };  template <typename K>  class Collinear_are_ordered_along_line_2  {    typedef typename K::RT              RT;    typedef typename K::Point_2         Point_2;#ifdef CGAL_kernel_exactness_preconditions     typedef typename K::Collinear_2 Collinear_2;    Collinear_2 c;#endif // CGAL_kernel_exactness_preconditions   public:    typedef bool             result_type;    typedef Arity_tag< 3 >   Arity;#ifdef CGAL_kernel_exactness_preconditions     Collinear_are_ordered_along_line_2() {}    Collinear_are_ordered_along_line_2(const Collinear_2& c_) : c(c_) {}#endif // CGAL_kernel_exactness_preconditions     bool    operator()(const Point_2& p, const Point_2& q, const Point_2& r) const    {      CGAL_kernel_exactness_precondition( c(p, q, r) );      const RT& phx = p.hx();      const RT& phy = p.hy();      const RT& phw = p.hw();      const RT& qhx = q.hx();      const RT& qhy = q.hy();      const RT& qhw = q.hw();      const RT& rhx = r.hx();      const RT& rhy = r.hy();      const RT& rhw = r.hw();      if ( !(phx * rhw == rhx * phw ) )          // non-vertical ?	{	  return !( (  ( phx * qhw < qhx * phw)		       &&( rhx * qhw < qhx * rhw))		    ||(  ( qhx * phw < phx * qhw)			 &&( qhx * rhw < rhx * qhw)) );	}      else if ( !(phy * rhw == rhy * phw ) )	{	  return !( (  ( phy * qhw < qhy * phw)		       &&( rhy * qhw < qhy * rhw))		    ||(  ( qhy * phw < phy * qhw)			 &&( qhy * rhw < rhy * qhw)) );	}      else	return (( phx*qhw == qhx*phw) && ( phy*qhw == qhy*phw));    }  };  template <typename K>  class Collinear_are_ordered_along_line_3  {    typedef typename K::Point_3         Point_3;#ifdef CGAL_kernel_exactness_preconditions     typedef typename K::Collinear_3 Collinear_3;    Collinear_3 c;#endif // CGAL_kernel_exactness_preconditions   public:    typedef bool             result_type;    typedef Arity_tag< 3 >   Arity;#ifdef CGAL_kernel_exactness_preconditions     Collinear_are_ordered_along_line_3() {}    Collinear_are_ordered_along_line_3(const Collinear_3& c_) : c(c_) {}#endif // CGAL_kernel_exactness_preconditions     bool    operator()(const Point_3& p, const Point_3& q, const Point_3& r) const    {      CGAL_kernel_exactness_precondition( c(p, q, r) );      typedef typename K::RT RT;      const RT phx = p.hx();      const RT phw = p.hw();      const RT qhx = q.hx();      const RT qhw = q.hw();      const RT rhx = r.hx();      const RT rhw = r.hw();      const RT pqx = phx*qhw;      const RT qpx = qhx*phw;      const RT prx = phx*rhw;      const RT qrx = qhx*rhw;      const RT rqx = rhx*qhw;      const RT rpx = rhx*phw;      if ( prx != rpx )   // px != rx	{	  //    (px <= qx)&&(qx <= rx) || (px >= qx)&&(qx >= rx)	  // !(((qx <  px)||(rx <  qx))&&((px <  qx)||(qx <  rx)))	  return ! (   ((qpx < pqx) || (rqx < qrx))		       && ((pqx < qpx) || (qrx < rqx))  );	}      const RT phy = p.hy();      const RT qhy = q.hy();      const RT rhy = r.hy();      const RT pqy = phy*qhw;      const RT qpy = qhy*phw;      const RT pry = phy*rhw;      const RT qry = qhy*rhw;      const RT rqy = rhy*qhw;      const RT rpy = rhy*phw;      if ( pry != rpy )	{	  return ! (   ((qpy < pqy) || (rqy < qry))		       && ((pqy < qpy) || (qry < rqy))  );	}      const RT phz = p.hz();      const RT qhz = q.hz();      const RT rhz = r.hz();      const RT pqz = phz*qhw;      const RT qpz = qhz*phw;      const RT prz = phz*rhw;      const RT qrz = qhz*rhw;      const RT rqz = rhz*qhw;      const RT rpz = rhz*phw;      if ( prz != rpz )	{	  return ! (   ((qpz < pqz) || (rqz < qrz))		       && ((pqz < qpz) || (qrz < rqz))  );	}      // p == r      return  ((rqx == qrx) && (rqy == qry) && (rqz == qrz));    }    };  template <typename K>  class Collinear_are_strictly_ordered_along_line_2  {    typedef typename K::Point_2         Point_2;#ifdef CGAL_kernel_exactness_preconditions     typedef typename K::Collinear_2 Collinear_2;    Collinear_2 c;#endif // CGAL_kernel_exactness_preconditions   public:    typedef bool             result_type;    typedef Arity_tag< 3 >   Arity;#ifdef CGAL_kernel_exactness_preconditions     Collinear_are_strictly_ordered_along_line_2() {}    Collinear_are_strictly_ordered_along_line_2(const Collinear_2& c_) : c(c_)     {}#endif // CGAL_kernel_exactness_preconditions     bool    operator()(const Point_2& p, const Point_2& q, const Point_2& r) const    {      CGAL_kernel_exactness_precondition( c(p, q, r) );      typedef typename K::RT RT;      const RT& phx = p.hx();      const RT& phy = p.hy();      const RT& phw = p.hw();      const RT& qhx = q.hx();      const RT& qhy = q.hy();      const RT& qhw = q.hw();      const RT& rhx = r.hx();      const RT& rhy = r.hy();      const RT& rhw = r.hw();      if ( !(phx * rhw == rhx * phw ) )	{	  return (   ( phx * qhw < qhx * phw)		     &&( qhx * rhw < rhx * qhw))	    ||(   ( qhx * phw < phx * qhw)    // ( phx * qhw > qhx * phw)		  &&( rhx * qhw < qhx * rhw));  // ( qhx * rhw > rhx * qhw)	}      else	{	  return (   ( phy * qhw < qhy * phw)		     &&( qhy * rhw < rhy * qhw))	    ||(   ( qhy * phw < phy * qhw)    // ( phy * qhw > qhy * phw)		  &&( rhy * qhw < qhy * rhw));  // ( qhy * rhw > rhy * qhw)	}    }  };  template <typename K>  class Collinear_are_strictly_ordered_along_line_3  {    typedef typename K::Point_3         Point_3;    typedef typename K::Direction_3     Direction_3;#ifdef CGAL_kernel_exactness_preconditions     typedef typename K::Collinear_3 Collinear_3;    Collinear_3 c;#endif // CGAL_kernel_exactness_preconditions   public:    typedef bool             result_type;    typedef Arity_tag< 3 >   Arity;#ifdef CGAL_kernel_exactness_preconditions     Collinear_are_strictly_ordered_along_line_3() {}    Collinear_are_strictly_ordered_along_line_3(const Collinear_3& c_) : c(c_)    {}#endif // CGAL_kernel_exactness_preconditions     bool    operator()(const Point_3& p, const Point_3& q, const Point_3& r) const    {      CGAL_kernel_exactness_precondition( c(p, q, r) );      if ( p == r) return false;      Direction_3 dir_pq = (p - q).direction();      Direction_3 dir_rq = (r - q).direction();      return (dir_pq == -dir_rq);    }  // FIXME  };  template <typename K>  class Collinear_has_on_2  {    typedef typename K::Point_2               Point_2;    typedef typename K::Direction_2           Direction_2;    typedef typename K::Ray_2                 Ray_2;    typedef typename K::Segment_2             Segment_2;    typedef typename K::Construct_point_on_2  Construct_point_on_2;    typedef typename K::Compare_xy_2          Compare_xy_2;    typedef typename K::Collinear_are_ordered_along_line_2                                           Collinear_are_ordered_along_line_2;    Collinear_are_ordered_along_line_2 co;    Construct_point_on_2 cp;    Compare_xy_2 cxy;  public:    typedef bool             result_type;    typedef Arity_tag< 2 >   Arity;    Collinear_has_on_2() {}    Collinear_has_on_2(const Construct_point_on_2& cp_,		       const Compare_xy_2& cxy_)      : cp(cp_), cxy(cxy_)    {}    bool    operator()( const Ray_2& r, const Point_2& p) const    {      const Point_2 & source = cp(r,0);            return p == source || Direction_2(p - source) == r.direction();    } // FIXME      bool    operator()( const Segment_2& s, const Point_2& p) const    {       return co(cp(s,0), p, cp(s,1));    }  };  template <typename K>  class Collinear_2  {    typedef typename K::Point_2        Point_2;    typedef typename K::Orientation_2  Orientation_2;    Orientation_2 o;  public:    typedef bool             result_type;    typedef Arity_tag< 3 >   Arity;    Collinear_2() {}    Collinear_2(const Orientation_2 o_) : o(o_) {}    bool    operator()(const Point_2& p, const Point_2& q, const Point_2& r) const    {      typedef typename K::RT RT;      const RT& phx = p.hx();      const RT& phy = p.hy();      const RT& phw = p.hw();      const RT& qhx = q.hx();      const RT& qhy = q.hy();      const RT& qhw = q.hw();      const RT& rhx = r.hx();      const RT& rhy = r.hy();      const RT& rhw = r.hw();      const RT  RT0 = RT(0);      // | A B |      // | C D |

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?