Updates to Boolean_operations_2 Qt4 demo (drawing actual beziers)

This commit is contained in:
Fernando Cacciola 2009-08-11 23:05:13 +00:00
parent 919321e300
commit 5cae98b574
3 changed files with 113 additions and 39 deletions

View File

@ -738,7 +738,7 @@ Bezier_curve read_bezier_curve ( std::istream& is, bool aDoubleFormat )
is >> n;
// Read the control points.
std::vector<Bezier_rat_point> ctrl_pts (n);
std::vector<Bezier_rat_point> ctrl_pts;
for ( unsigned int k = 0; k < n; k++)
{
@ -754,12 +754,10 @@ Bezier_curve read_bezier_curve ( std::istream& is, bool aDoubleFormat )
is >> p ;
}
if ( k > 1 && ctrl_pts[k-1] == p )
if ( k == 0 || ctrl_pts[k-1] != p )
{
error("Bezier data contains consecutive identical control points.");
ctrl_pts.push_back(p) ;
}
ctrl_pts[k] = p ;
}
return Bezier_curve(ctrl_pts.begin(),ctrl_pts.end());
@ -816,18 +814,20 @@ bool read_bezier ( QString aFileName, Bezier_polygon_set& rSet )
Bezier_traits::Make_x_monotone_2 make_x_monotone = traits.make_x_monotone_2_object();
Bezier_curve B = read_bezier_curve(in_file, lDoubleFormat);
TRACE( "region " << r << " boundary " << b << " curve " << k );
make_x_monotone (B, std::back_inserter (x_objs));
for (xoit = x_objs.begin(); xoit != x_objs.end(); ++xoit)
if ( B.number_of_control_points() >= 2 )
{
if (CGAL::assign (xcv, *xoit))
TRACE( "region " << r << " boundary " << b << " curve " << k );
make_x_monotone (B, std::back_inserter (x_objs));
for (xoit = x_objs.begin(); xoit != x_objs.end(); ++xoit)
{
TRACE( " X montonote: " << xcv.source() << " -> " << xcv.target() << ( xcv.is_directed_right() ? " RIGHT":" LEFT") << ( xcv.is_vertical() ? " VERTICAL" : "")) ;
xcvs.push_back (xcv);
}
if (CGAL::assign (xcv, *xoit))
{
TRACE( " X montonote: " << xcv.source() << " -> " << xcv.target() << ( xcv.is_directed_right() ? " RIGHT":" LEFT") << ( xcv.is_vertical() ? " VERTICAL" : "")) ;
xcvs.push_back (xcv);
}
}
}
}

View File

@ -24,6 +24,7 @@
#include <list>
#include <boost/optional.hpp>
#include <boost/utility.hpp>
#include <CGAL/function_objects.h>
#include <CGAL/Bbox_2.h>
@ -64,6 +65,25 @@ namespace Qt {
typedef typename PS::Polygon_2 Polygon_2 ;
typedef typename PS::Traits_2 Traits_2;
} ;
template<class Point>
struct arbitrary_point_helper
{
static std::pair<double,double> approximate( Point const& p )
{
return std::make_pair( to_double(p.x()), to_double(p.y()) ) ;
}
};
template <class R, class A, class N, class B>
struct arbitrary_point_helper< _Bezier_point_2<R,A,N,B> >
{
static std::pair<double,double> approximate( _Bezier_point_2<R,A,N,B> const& p )
{
return p.approximate();
}
} ;
}
template <class General_polygon_set_, class Compute_XM_curve_bbox_, class Draw_XM_curve_>
@ -83,6 +103,7 @@ class GeneralPolygonSetGraphicsItem : public GraphicsItem
typedef typename General_polygon_with_holes_vector::const_iterator General_pwh_const_iterator ;
typedef typename General_polygon_with_holes::Hole_const_iterator General_hole_const_itertator ;
typedef typename General_polygon::Curve_const_iterator General_curve_const_iterator ;
typedef typename General_polygon::X_monotone_curve_2 General_X_monotone_curve_2 ;
typedef Converter< Simple_cartesian<double> > ToQtConverter;
@ -224,10 +245,57 @@ template <class G, class B, class D>
template<class Visitor>
void GeneralPolygonSetGraphicsItem<G,B,D>::traverse_polygon( General_polygon const& aP, Visitor& aVisitor)
{
int c = 0 ;
for( General_curve_const_iterator cit = aP.curves_begin(); cit != aP.curves_end(); ++ cit )
//
// Hack to workaround some bezier incosistency proble where the ordering of the curves within the sequence is reversed
// w.r.t to the orientation of each curve in turn.
//
typedef std::vector<General_X_monotone_curve_2> XMC_vector ;
typedef typename General_X_monotone_curve_2::Point_2 Point ;
XMC_vector curves ;
std::copy(aP.curves_begin(),aP.curves_end(), std::back_inserter(curves) ) ;
bool lFwd = true ;
if ( curves.size() >= 2 )
{
aVisitor(*cit,c++);
double s0x ;
double s0y ;
double t0x ;
double t0y ;
double s1x ;
double s1y ;
double t1x ;
double t1y ;
boost::tie(s0x,s0y) = CGALi::arbitrary_point_helper<Point>::approximate(curves[0].source());
boost::tie(t0x,t0y) = CGALi::arbitrary_point_helper<Point>::approximate(curves[0].target());
boost::tie(s1x,s1y) = CGALi::arbitrary_point_helper<Point>::approximate(curves[1].source());
boost::tie(t1x,t1y) = CGALi::arbitrary_point_helper<Point>::approximate(curves[1].target());
// squared distance between c0.target <-> c1.source
double dts = ((s1x-t0x)*(s1x-t0x))+((s1y-t0y)*(s1y-t0y));
// squared distance between c1.source <-> c0.target
double dst = ((s0x-t1x)*(s0x-t1x))+((s0y-t1y)*(s0y-t1y));
// The curves are reversed if c1 is followed by c0
if ( dst < dts )
lFwd = false ;
}
int c = 0 ;
if ( lFwd )
{
for( typename XMC_vector::const_iterator cit = curves.begin(); cit != curves.end(); ++ cit )
aVisitor(*cit,c++);
}
else
{
for( typename XMC_vector::const_reverse_iterator cit = curves.rbegin(); cit != curves.rend(); ++ cit )
aVisitor(*cit,c++);
}
}

View File

@ -141,11 +141,11 @@ struct Bezier_helper
}
template<class OutputIterator>
static void get_control_points ( Bezier_curve const& aCurve, OutputIterator aOut )
static void get_control_points ( Bezier_curve const& aCurve, bool aFwd, OutputIterator aOut )
{
int nc = aCurve.number_of_control_points() ;
for ( int i = 0 ; i < nc ; ++ i )
for ( int i = aFwd ? 0 : nc - 1 ; aFwd ? i < nc : i >= 0 ; aFwd ? ++ i : -- i )
{
*aOut++ = Linear_point( CGAL::to_double( aCurve.control_point(i).x() )
, CGAL::to_double( aCurve.control_point(i).y() )
@ -154,28 +154,32 @@ struct Bezier_helper
}
template<class OutputIterator>
static void clip ( Bezier_curve const& aCurve, double aS, double aT, OutputIterator aOut )
static void clip ( Bezier_curve const& aCurve, double aS, double aT, bool aFwd, OutputIterator aOut )
{
std::vector<Linear_point> lQ ;
get_control_points(aCurve, std::back_inserter(lQ) ) ;
get_control_points(aCurve, aFwd, std::back_inserter(lQ) ) ;
int nc = aCurve.number_of_control_points() ;
int ncc = nc - 1 ;
double lAlfa = aS ;
double lBeta = (aT-aS) / ( 1.0 - aS ) ;
for ( int i = 1 ; i <= ncc ; ++ i )
{
for ( int j = 0 ; j < ncc ; ++ j )
lQ[j] = lQ[j] + lAlfa * ( lQ[j+1] - lQ[j] ) ;
for ( int j = nc - i ; j <= ncc ; ++ j )
lQ[j] = lQ[j-1] + lBeta * ( lQ[j] - lQ[j-1] ) ;
}
if ( aS >= 0.0 || aT <= 1.0 )
{
int nc = aCurve.number_of_control_points() ;
int ncc = nc - 1 ;
double lAlfa = aS ;
double lBeta = (aT-aS) / ( 1.0 - aS ) ;
for ( int i = 1 ; i <= ncc ; ++ i )
{
for ( int j = 0 ; j < ncc ; ++ j )
lQ[j] = lQ[j] + lAlfa * ( lQ[j+1] - lQ[j] ) ;
for ( int j = nc - i ; j <= ncc ; ++ j )
lQ[j] = lQ[j-1] + lBeta * ( lQ[j] - lQ[j-1] ) ;
}
}
std::copy(lQ.begin(), lQ.end(), aOut );
}
template<class OutputIterator>
@ -186,12 +190,12 @@ struct Bezier_helper
double lS = get_approximated_endpoint_parameter(aBXMC.source(), lBC, aBXMC.xid());
double lT = get_approximated_endpoint_parameter(aBXMC.target(), lBC, aBXMC.xid());
bool lFwd = aBXMC.is_vertical() || lS <= lT ;
bool lFwd = lS <= lT ;
double lMin = lFwd ? lS : 1.0 - lS ;
double lMax = lFwd ? lT : 1.0 - lT ;
clip(lBC, lMin, lMax, aOut );
clip(lBC, lMin, lMax, lFwd, aOut );
}
} ;
@ -199,9 +203,11 @@ struct Compute_bezier_X_monotone_cuve_bbox
{
CGAL::Bbox_2 operator()( Bezier_X_monotone_curve const& aCurve ) const
{
return aCurve.supporting_curve().bbox();
std::vector<Linear_point> lQ ;
Bezier_helper::get_control_points(aCurve.supporting_curve(), std::back_inserter(lQ) ) ;
Bezier_helper::get_control_points(aCurve.supporting_curve(), true, std::back_inserter(lQ) ) ;
return CGAL::bbox_2(lQ.begin(),lQ.end());
}