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; is >> n;
// Read the control points. // 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++) for ( unsigned int k = 0; k < n; k++)
{ {
@ -754,12 +754,10 @@ Bezier_curve read_bezier_curve ( std::istream& is, bool aDoubleFormat )
is >> p ; 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()); return Bezier_curve(ctrl_pts.begin(),ctrl_pts.end());
@ -816,17 +814,19 @@ 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_traits::Make_x_monotone_2 make_x_monotone = traits.make_x_monotone_2_object();
Bezier_curve B = read_bezier_curve(in_file, lDoubleFormat); Bezier_curve B = read_bezier_curve(in_file, lDoubleFormat);
if ( B.number_of_control_points() >= 2 )
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 (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" : "")) ; if (CGAL::assign (xcv, *xoit))
xcvs.push_back (xcv); {
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 <list>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/utility.hpp>
#include <CGAL/function_objects.h> #include <CGAL/function_objects.h>
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
@ -64,6 +65,25 @@ namespace Qt {
typedef typename PS::Polygon_2 Polygon_2 ; typedef typename PS::Polygon_2 Polygon_2 ;
typedef typename PS::Traits_2 Traits_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_> 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_vector::const_iterator General_pwh_const_iterator ;
typedef typename General_polygon_with_holes::Hole_const_iterator General_hole_const_itertator ; 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::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; typedef Converter< Simple_cartesian<double> > ToQtConverter;
@ -224,10 +245,57 @@ template <class G, class B, class D>
template<class Visitor> template<class Visitor>
void GeneralPolygonSetGraphicsItem<G,B,D>::traverse_polygon( General_polygon const& aP, Visitor& aVisitor) 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> 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() ; 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() ) *aOut++ = Linear_point( CGAL::to_double( aCurve.control_point(i).x() )
, CGAL::to_double( aCurve.control_point(i).y() ) , CGAL::to_double( aCurve.control_point(i).y() )
@ -154,28 +154,32 @@ struct Bezier_helper
} }
template<class OutputIterator> 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 ; 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() ; if ( aS >= 0.0 || aT <= 1.0 )
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 ) int nc = aCurve.number_of_control_points() ;
lQ[j] = lQ[j] + lAlfa * ( lQ[j+1] - lQ[j] ) ; int ncc = nc - 1 ;
for ( int j = nc - i ; j <= ncc ; ++ j ) double lAlfa = aS ;
lQ[j] = lQ[j-1] + lBeta * ( lQ[j] - lQ[j-1] ) ; 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 ); std::copy(lQ.begin(), lQ.end(), aOut );
} }
template<class OutputIterator> template<class OutputIterator>
@ -186,12 +190,12 @@ struct Bezier_helper
double lS = get_approximated_endpoint_parameter(aBXMC.source(), lBC, aBXMC.xid()); double lS = get_approximated_endpoint_parameter(aBXMC.source(), lBC, aBXMC.xid());
double lT = get_approximated_endpoint_parameter(aBXMC.target(), 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 lMin = lFwd ? lS : 1.0 - lS ;
double lMax = lFwd ? lT : 1.0 - lT ; 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 CGAL::Bbox_2 operator()( Bezier_X_monotone_curve const& aCurve ) const
{ {
return aCurve.supporting_curve().bbox();
std::vector<Linear_point> lQ ; 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()); return CGAL::bbox_2(lQ.begin(),lQ.end());
} }