33#define WITH_ASSERTIONS
44#define WITH_BEZIERCLIP_TEST
66 while( k-- &&
n ) res *=
n--;
90 const double len(std::hypot(
line.a,
line.b));
109 if( dP2 * dP3 > 0.0 )
111 line.dMin = 3.0/4.0 * std::min(0.0, std::min(dP2, dP3));
112 line.dMax = 3.0/4.0 * std::max(0.0, std::max(dP2, dP3));
116 line.dMin = 4.0/9.0 * std::min(0.0, std::min(dP2, dP3));
117 line.dMax = 4.0/9.0 * std::max(0.0, std::max(dP2, dP3));
125 leftTop.
x = std::min( c1.
p0.
x, std::min( c1.
p1.
x, std::min( c1.
p2.
x, c1.
p3.
x ) ) );
126 leftTop.
y = std::min( c1.
p0.
y, std::min( c1.
p1.
y, std::min( c1.
p2.
y, c1.
p3.
y ) ) );
127 rightBottom.
x = std::max( c1.
p0.
x, std::max( c1.
p1.
x, std::max( c1.
p2.
x, c1.
p3.
x ) ) );
128 rightBottom.
y = std::max( c1.
p0.
y, std::max( c1.
p1.
y, std::max( c1.
p2.
y, c1.
p3.
y ) ) );
143 if( std::min(rb1.
x, rb2.
x) < std::max(
lt1.x,
lt2.x) ||
144 std::min(rb1.
y, rb2.
y) < std::max(
lt1.y,
lt2.y) )
171 double currLowerT( 1.0 );
174 double currHigherT( 0.0 );
176 if( convHull.size() <= 1 )
183 bool bIntersection(
false );
185 for( Polygon2D::size_type
i=0;
i<convHull.size(); ++
i )
190 if(
i+1 == convHull.size() )
214 const double r_y( p1.
y - p0.
y );
225 currLowerT = std::min(currLowerT, std::min(p0.
x, p1.
x));
226 currHigherT = std::max(currHigherT, std::max(p0.
x, p1.
x));
233 const double r_x( p1.
x - p0.
x );
236 const double currTLow( (lowerYBound - p0.
y) * r_x / r_y + p0.
x );
239 const double currTHigh( (upperYBound - p0.
y) * r_x / r_y + p0.
x );
241 currLowerT = std::min(currLowerT, std::min(currTLow, currTHigh));
242 currHigherT = std::max(currHigherT, std::max(currTLow, currTHigh));
247 bIntersection =
true;
251#ifndef WITH_SAFEPARAMBASE_TEST
253 t1 = std::max(0.0, currLowerT);
254 t2 = std::min(1.0, currHigherT);
257 return bIntersection;
279 poly[1] =
Point2D(1.0/3.0, c1);
280 poly[2] =
Point2D(2.0/3.0, c2);
283#ifndef WITH_SAFEPARAM_DETAILED_TEST
292 std::cout <<
"# convex hull testing" << std::endl
298 << poly[3].x <<
",t),bez("
302 << poly[3].y <<
",t), "
303 <<
"t, " << bounds.
dMin <<
", "
304 <<
"t, " << bounds.
dMax <<
", "
307 <<
"'-' using ($1):($2) title \"control polygon\" with lp, "
308 <<
"'-' using ($1):($2) title \"convex hull\" with lp" << std::endl;
311 for( k=0; k<poly.size(); ++k )
313 std::cout << poly[k].x <<
" " << poly[k].y << std::endl;
315 std::cout << poly[0].x <<
" " << poly[0].y << std::endl;
316 std::cout <<
"e" << std::endl;
318 for( k=0; k<convHull.size(); ++k )
320 std::cout << convHull[k].x <<
" " << convHull[k].y << std::endl;
322 std::cout << convHull[0].x <<
" " << convHull[0].y << std::endl;
323 std::cout <<
"e" << std::endl;
366 const double Hx ( (1.0 -
t)*input.
p1.
x +
t*input.
p2.
x ), Hy ( (1.0 -
t)*input.
p1.
y +
t*input.
p2.
y );
367 part1.
p2.
x = (1.0 -
t)*part1.
p1.
x +
t*Hx; part1.
p2.
y = (1.0 -
t)*part1.
p1.
y +
t*Hy;
370 part2.
p1.
x = (1.0 -
t)*Hx +
t*part2.
p2.
x; part2.
p1.
y = (1.0 -
t)*Hy +
t*part2.
p2.
y;
379 static int offset = 0;
381 std::cout <<
"# safe param range testing" << std::endl
382 <<
"plot [t=0.0:1.0] ";
397 << c1.
p0.
x+offset <<
","
398 << c1.
p1.
x+offset <<
","
399 << c1.
p2.
x+offset <<
","
400 << c1.
p3.
x+offset <<
",t),bez("
404 << c1.
p3.
y <<
",t), bez("
405 << c2.
p0.
x+offset <<
","
406 << c2.
p1.
x+offset <<
","
407 << c2.
p2.
x+offset <<
","
408 << c2.
p3.
x+offset <<
",t),bez("
412 << c2.
p3.
y <<
",t), "
415 << c1_part1.
p0.
x+offset <<
","
416 << c1_part1.
p1.
x+offset <<
","
417 << c1_part1.
p2.
x+offset <<
","
418 << c1_part1.
p3.
x+offset <<
",t),bez("
419 << c1_part1.
p0.
y <<
","
420 << c1_part1.
p1.
y <<
","
421 << c1_part1.
p2.
y <<
","
422 << c1_part1.
p3.
y <<
",t), "
426 << c2_part.
p0.
x+offset <<
","
427 << c2_part.
p1.
x+offset <<
","
428 << c2_part.
p2.
x+offset <<
","
429 << c2_part.
p3.
x+offset <<
",t),bez("
430 << c2_part.
p0.
y <<
","
431 << c2_part.
p1.
y <<
","
432 << c2_part.
p2.
y <<
","
433 << c2_part.
p3.
y <<
",t), "
436 << bounds_c2.
a <<
","
437 << bounds_c2.
b <<
","
438 << bounds_c2.
c <<
",t)+" << offset <<
", liney("
439 << bounds_c2.
a <<
","
440 << bounds_c2.
b <<
","
441 << bounds_c2.
c <<
",t) title \"fat line (center)\", linex("
442 << bounds_c2.
a <<
","
443 << bounds_c2.
b <<
","
444 << bounds_c2.
c-bounds_c2.
dMin <<
",t)+" << offset <<
", liney("
445 << bounds_c2.
a <<
","
446 << bounds_c2.
b <<
","
447 << bounds_c2.
c-bounds_c2.
dMin <<
",t) title \"fat line (min) \", linex("
448 << bounds_c2.
a <<
","
449 << bounds_c2.
b <<
","
450 << bounds_c2.
c-bounds_c2.
dMax <<
",t)+" << offset <<
", liney("
451 << bounds_c2.
a <<
","
452 << bounds_c2.
b <<
","
453 << bounds_c2.
c-bounds_c2.
dMax <<
",t) title \"fat line (max) \"" << std::endl;
460 double t1_c1,
double t2_c1 )
462 static int offset = 0;
464 std::cout <<
"# final result" << std::endl
465 <<
"plot [t=0.0:1.0] ";
468 << c1.
p0.
x+offset <<
","
469 << c1.
p1.
x+offset <<
","
470 << c1.
p2.
x+offset <<
","
471 << c1.
p3.
x+offset <<
",t),bez("
475 << c1.
p3.
y <<
",t), bez("
476 << c1_part.
p0.
x+offset <<
","
477 << c1_part.
p1.
x+offset <<
","
478 << c1_part.
p2.
x+offset <<
","
479 << c1_part.
p3.
x+offset <<
",t),bez("
480 << c1_part.
p0.
y <<
","
481 << c1_part.
p1.
y <<
","
482 << c1_part.
p2.
y <<
","
483 << c1_part.
p3.
y <<
",t), "
484 <<
" pointmarkx(bez("
485 << c1.
p0.
x+offset <<
","
486 << c1.
p1.
x+offset <<
","
487 << c1.
p2.
x+offset <<
","
488 << c1.
p3.
x+offset <<
","
490 <<
" pointmarky(bez("
496 <<
" pointmarkx(bez("
497 << c1.
p0.
x+offset <<
","
498 << c1.
p1.
x+offset <<
","
499 << c1.
p2.
x+offset <<
","
500 << c1.
p3.
x+offset <<
","
502 <<
" pointmarky(bez("
510 << c2.
p0.
x+offset <<
","
511 << c2.
p1.
x+offset <<
","
512 << c2.
p2.
x+offset <<
","
513 << c2.
p3.
x+offset <<
",t),bez("
517 << c2.
p3.
y <<
",t), "
519 << c2_part.
p0.
x+offset <<
","
520 << c2_part.
p1.
x+offset <<
","
521 << c2_part.
p2.
x+offset <<
","
522 << c2_part.
p3.
x+offset <<
",t),bez("
523 << c2_part.
p0.
y <<
","
524 << c2_part.
p1.
y <<
","
525 << c2_part.
p2.
y <<
","
526 << c2_part.
p3.
y <<
",t)" << std::endl;
617 const double minPivotValue( 1.0e-20 );
671 fMatrix[0] = c.
p1.
x - c.
p0.
x;
672 fMatrix[1] = c.
p2.
x - c.
p3.
x;
673 fMatrix[2] = (c.
p3.
y - c.
p0.
y)/3.0;
674 fMatrix[3] = c.
p0.
y - c.
p1.
y;
675 fMatrix[4] = c.
p3.
y - c.
p2.
y;
676 fMatrix[5] = (c.
p3.
x - c.
p0.
x)/3.0;
679 if( !
solve(fMatrix, 2, 3, fRes, minPivotValue) )
687 std::cerr <<
"Matrix singular!" << std::endl;
803 const int i_card( 2*
n );
804 const int j_card(
n + 1 );
805 const int k_max(
n-1 );
806 Polygon2D controlPolygon( i_card*j_card );
810 for(
i=0;
i<i_card; ++
i )
812 for( j=0; j<j_card; ++j )
815 for(
d=0.0, k=std::max(0,
i-
n); k<=k_max && k<=
i; ++k )
818 assert(k>=0 && k<=
n-1);
819 assert(l>=0 && l<=
n);
826 ( (curve[k+1].
x - curve[k].
x)*(curve[l].x - focus[j].x) +
827 (curve[k+1].
y - curve[k].
y)*(curve[l].y - focus[j].y) );
832 controlPolygon[
i*j_card + j ] =
Point2D(
i/(2.0*
n-1.0),
d );
836#ifndef WITH_SAFEFOCUSPARAM_DETAILED_TEST
847 std::cout <<
"# convex hull testing (focus)" << std::endl
849 std::cout <<
"'-' using ($1):($2) title \"control polygon\" with lp, "
850 <<
"'-' using ($1):($2) title \"convex hull\" with lp" << std::endl;
855 std::cout << controlPolygon[
count].x <<
" " << controlPolygon[
count].y << std::endl;
857 std::cout << controlPolygon[0].x <<
" " << controlPolygon[0].y << std::endl;
858 std::cout <<
"e" << std::endl;
862 std::cout << convHull[
count].x <<
" " << convHull[
count].y << std::endl;
864 std::cout << convHull[0].x <<
" " << convHull[0].y << std::endl;
865 std::cout <<
"e" << std::endl;
900template <
class Functor>
void Impl_applySafeRanges_rec( std::back_insert_iterator< std::vector< std::pair<double, double> > >& result,
902 const Functor& safeRangeFunctor,
927 for(
int i=0;
i<recursionLevel; ++
i ) std::cerr <<
" ";
928 if( recursionLevel % 2 )
930 std::cerr << std::endl <<
"level: " << recursionLevel
932 << last_t1_c2 + (last_t2_c2 - last_t1_c2)/2.0
933 <<
", c1: " << last_t1_c2 <<
" " << last_t2_c2
934 <<
", c2: " << last_t1_c1 <<
" " << last_t2_c1
939 std::cerr << std::endl <<
"level: " << recursionLevel
941 << last_t1_c1 + (last_t2_c1 - last_t1_c1)/2.0
942 <<
", c1: " << last_t1_c1 <<
" " << last_t2_c1
943 <<
", c2: " << last_t1_c2 <<
" " << last_t2_c2
959 if( safeRangeFunctor( t1_c1, t2_c1, c1_orig, c1_part, c2_orig, c2_part ) )
975 t1_c1 = std::max(t1_c1, last_t1_c1);
976 t2_c1 = std::min(t2_c1, last_t2_c1);
985 if( fabs(last_t2_c1 - last_t1_c1) < 0.0001 &&
986 fabs(last_t2_c2 - last_t1_c2) < 0.0001 )
988 if( fabs(last_t2_c1 - last_t1_c1) < 0.01 &&
989 fabs(last_t2_c2 - last_t1_c2) < 0.01 )
993 if( recursionLevel % 2 )
996 *
result++ = std::make_pair( last_t1_c2 + (last_t2_c2 - last_t1_c2)/2.0,
997 last_t1_c1 + (last_t2_c1 - last_t1_c1)/2.0 );
1001 *
result++ = std::make_pair( last_t1_c1 + (last_t2_c1 - last_t1_c1)/2.0,
1002 last_t1_c2 + (last_t2_c2 - last_t1_c2)/2.0 );
1013 safeRangeFunctor( t1_c1, t2_c1, c1_orig, c1_part, c2_orig, c2_part );
1033 double intervalMiddle;
1035 if( last_t2_c1 - last_t1_c1 > last_t2_c2 - last_t1_c2 )
1040 intervalMiddle = last_t1_c1 + (last_t2_c1 - last_t1_c1)/2.0;
1050 c2_orig, c2_part, last_t1_c2, last_t2_c2,
1051 c1_orig, part1, last_t1_c1, intervalMiddle );
1054 c2_orig, c2_part, last_t1_c2, last_t2_c2,
1055 c1_orig, part2, intervalMiddle, last_t2_c1 );
1062 intervalMiddle = last_t1_c2 + (last_t2_c2 - last_t1_c2)/2.0;
1072 c2_orig, part1, last_t1_c2, intervalMiddle,
1073 c1_orig, c1_part, last_t1_c1, last_t2_c1 );
1076 c2_orig, part2, intervalMiddle, last_t2_c2,
1077 c1_orig, c1_part, last_t1_c1, last_t2_c1 );
1105 c2_orig, c2_part, last_t1_c2, last_t2_c2,
1106 c1_orig, c1_part1, t1_c1, t2_c1 );
1120 const Bezier& c2_part )
const
1133 const Bezier& c2_part )
const
1146 std::cerr <<
"range: " << t2_c1 - t1_c1 <<
", ret: " << bRet << std::endl;
1162void clipBezier( std::back_insert_iterator< std::vector< std::pair<double, double> > >& result,
1178 std::vector< std::pair<double,double> > results;
1179 std::back_insert_iterator< std::vector< std::pair<double, double> > > ii(results);
1181 Impl_calcCollinearNormals( ii, delta, 0, c1, c1, 0.0, 1.0, c2, c2, 0.0, 1.0 );
1192 std::vector< Bezier > c1_segments( results.size()+1 );
1193 std::vector< Bezier > c2_segments( results.size()+1 );
1194 Bezier c1_remainder( c1 );
1195 Bezier c2_remainder( c2 );
1197 for(
i=0;
i<results.size(); ++
i )
1201 c1_remainder = c1_part2;
1205 c2_remainder = c2_part2;
1207 c1_segments[
i] = c1_remainder;
1208 c2_segments[
i] = c2_remainder;
1212 unsigned int c1_curr, c2_curr;
1213 for( c1_curr=0; c1_curr<c1_segments.size(); ++c1_curr )
1215 for( c2_curr=0; c2_curr<c2_segments.size(); ++c2_curr )
1217 if( c1_curr != c2_curr )
1219 Impl_clipBezier_rec(
result, delta, 0,
1220 c1_segments[c1_curr], c1_segments[c1_curr],
1222 c2_segments[c2_curr], c2_segments[c2_curr],
1228 Impl_applySafeRanges_rec(
result, delta,
BezierTangencyFunctor(), 0, c1, c1, 0.0, 1.0, c2, c2, 0.0, 1.0 );
1234int main(
int argc,
const char *argv[])
1236 double curr_Offset( 0 );
1304 std::cout <<
"#!/usr/bin/gnuplot -persist" << std::endl
1306 <<
"# automatically generated by bezierclip, don't change!" << std::endl
1308 <<
"set parametric" << std::endl
1309 <<
"bez(p,q,r,s,t) = p*(1-t)**3+q*3*(1-t)**2*t+r*3*(1-t)*t**2+s*t**3" << std::endl
1310 <<
"bezd(p,q,r,s,t) = 3*(q-p)*(1-t)**2+6*(r-q)*(1-t)*t+3*(s-r)*t**2" << std::endl
1311 <<
"pointmarkx(c,t) = c-0.03*t" << std::endl
1312 <<
"pointmarky(c,t) = c+0.03*t" << std::endl
1313 <<
"linex(a,b,c,t) = a*-c + t*-b" << std::endl
1314 <<
"liney(a,b,c,t) = b*-c + t*a" << std::endl << std::endl
1315 <<
"# end of setup" << std::endl << std::endl;
1317#ifdef WITH_CONVEXHULL_TEST
1319 const double convHull_xOffset( curr_Offset );
1321 std::cout <<
"# convex hull testing" << std::endl
1323 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1326 aTestPoly[0] = someCurves[
i].
p0;
1327 aTestPoly[1] = someCurves[
i].
p1;
1328 aTestPoly[2] = someCurves[
i].
p2;
1329 aTestPoly[3] = someCurves[
i].
p3;
1331 aTestPoly[0].
x += convHull_xOffset;
1332 aTestPoly[1].x += convHull_xOffset;
1333 aTestPoly[2].x += convHull_xOffset;
1334 aTestPoly[3].x += convHull_xOffset;
1336 std::cout <<
" bez("
1337 << aTestPoly[0].x <<
","
1338 << aTestPoly[1].x <<
","
1339 << aTestPoly[2].x <<
","
1340 << aTestPoly[3].x <<
",t),bez("
1341 << aTestPoly[0].y <<
","
1342 << aTestPoly[1].y <<
","
1343 << aTestPoly[2].y <<
","
1344 << aTestPoly[3].y <<
",t), '-' using ($1):($2) title \"convex hull " <<
i <<
"\" with lp";
1346 if(
i+1<
sizeof(someCurves)/
sizeof(
Bezier) )
1347 std::cout <<
",\\" << std::endl;
1349 std::cout << std::endl;
1351 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1354 aTestPoly[0] = someCurves[
i].
p0;
1355 aTestPoly[1] = someCurves[
i].
p1;
1356 aTestPoly[2] = someCurves[
i].
p2;
1357 aTestPoly[3] = someCurves[
i].
p3;
1359 aTestPoly[0].
x += convHull_xOffset;
1360 aTestPoly[1].x += convHull_xOffset;
1361 aTestPoly[2].x += convHull_xOffset;
1362 aTestPoly[3].x += convHull_xOffset;
1366 for( k=0; k<convHull.size(); ++k )
1368 std::cout << convHull[k].x <<
" " << convHull[k].y << std::endl;
1370 std::cout << convHull[0].x <<
" " << convHull[0].y << std::endl;
1371 std::cout <<
"e" << std::endl;
1375#ifdef WITH_MULTISUBDIVIDE_TEST
1377 const double multiSubdivide_xOffset( curr_Offset );
1379 std::cout <<
"# multi subdivide testing" << std::endl
1381 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1388 c.
p0.
x += multiSubdivide_xOffset;
1389 c.
p1.
x += multiSubdivide_xOffset;
1390 c.
p2.
x += multiSubdivide_xOffset;
1391 c.
p3.
x += multiSubdivide_xOffset;
1393 const double t1( 0.1+
i/(3.0*
sizeof(someCurves)/
sizeof(
Bezier)) );
1394 const double t2( 0.9-
i/(3.0*
sizeof(someCurves)/
sizeof(
Bezier)) );
1411 std::cout <<
" bez("
1412 << c1_part1.
p0.
x <<
","
1413 << c1_part1.
p1.
x <<
","
1414 << c1_part1.
p2.
x <<
","
1415 << c1_part1.
p3.
x <<
",t), bez("
1416 << c1_part1.
p0.
y+0.01 <<
","
1417 << c1_part1.
p1.
y+0.01 <<
","
1418 << c1_part1.
p2.
y+0.01 <<
","
1419 << c1_part1.
p3.
y+0.01 <<
",t) title \"middle " <<
i <<
"\", "
1421 << c1_part2.
p0.
x <<
","
1422 << c1_part2.
p1.
x <<
","
1423 << c1_part2.
p2.
x <<
","
1424 << c1_part2.
p3.
x <<
",t), bez("
1425 << c1_part2.
p0.
y <<
","
1426 << c1_part2.
p1.
y <<
","
1427 << c1_part2.
p2.
y <<
","
1428 << c1_part2.
p3.
y <<
",t) title \"right " <<
i <<
"\", "
1430 << c1_part3.
p0.
x <<
","
1431 << c1_part3.
p1.
x <<
","
1432 << c1_part3.
p2.
x <<
","
1433 << c1_part3.
p3.
x <<
",t), bez("
1434 << c1_part3.
p0.
y <<
","
1435 << c1_part3.
p1.
y <<
","
1436 << c1_part3.
p2.
y <<
","
1437 << c1_part3.
p3.
y <<
",t) title \"left " <<
i <<
"\"";
1439 if(
i+1<
sizeof(someCurves)/
sizeof(
Bezier) )
1440 std::cout <<
",\\" << std::endl;
1442 std::cout << std::endl;
1446#ifdef WITH_FATLINE_TEST
1448 const double fatLine_xOffset( curr_Offset );
1450 std::cout <<
"# fat line testing" << std::endl
1452 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1456 c.
p0.
x += fatLine_xOffset;
1457 c.
p1.
x += fatLine_xOffset;
1458 c.
p2.
x += fatLine_xOffset;
1459 c.
p3.
x += fatLine_xOffset;
1465 std::cout <<
" bez("
1469 << c.
p3.
x <<
",t), bez("
1473 << c.
p3.
y <<
",t) title \"bezier " <<
i <<
"\", linex("
1476 <<
line.c <<
",t), liney("
1479 <<
line.c <<
",t) title \"fat line (center) on " <<
i <<
"\", linex("
1482 <<
line.c-
line.dMin <<
",t), liney("
1485 <<
line.c-
line.dMin <<
",t) title \"fat line (min) on " <<
i <<
"\", linex("
1488 <<
line.c-
line.dMax <<
",t), liney("
1491 <<
line.c-
line.dMax <<
",t) title \"fat line (max) on " <<
i <<
"\"";
1493 if(
i+1<
sizeof(someCurves)/
sizeof(
Bezier) )
1494 std::cout <<
",\\" << std::endl;
1496 std::cout << std::endl;
1500#ifdef WITH_CALCFOCUS_TEST
1502 const double focus_xOffset( curr_Offset );
1504 std::cout <<
"# focus line testing" << std::endl
1506 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1510 c.
p0.
x += focus_xOffset;
1511 c.
p1.
x += focus_xOffset;
1512 c.
p2.
x += focus_xOffset;
1513 c.
p3.
x += focus_xOffset;
1519 std::cout <<
" bez("
1523 << c.
p3.
x <<
",t), bez("
1527 << c.
p3.
y <<
",t) title \"bezier " <<
i <<
"\", bez("
1528 << focus.
p0.
x <<
","
1529 << focus.
p1.
x <<
","
1530 << focus.
p2.
x <<
","
1531 << focus.
p3.
x <<
",t), bez("
1532 << focus.
p0.
y <<
","
1533 << focus.
p1.
y <<
","
1534 << focus.
p2.
y <<
","
1535 << focus.
p3.
y <<
",t) title \"focus " <<
i <<
"\"";
1537 if(
i+1<
sizeof(someCurves)/
sizeof(
Bezier) )
1538 std::cout <<
",\\" << std::endl;
1540 std::cout << std::endl;
1544#ifdef WITH_SAFEPARAMBASE_TEST
1546 double safeParamsBase_xOffset( curr_Offset );
1547 std::cout <<
"# safe param base method testing" << std::endl
1549 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1553 c.
p0.
x += safeParamsBase_xOffset;
1554 c.
p1.
x += safeParamsBase_xOffset;
1555 c.
p2.
x += safeParamsBase_xOffset;
1556 c.
p3.
x += safeParamsBase_xOffset;
1570 std::cout <<
" bez("
1574 << poly[3].x <<
",t),bez("
1578 << poly[3].y <<
",t), "
1579 <<
"t+" << safeParamsBase_xOffset <<
", 0, "
1580 <<
"t+" << safeParamsBase_xOffset <<
", 1, ";
1583 std::cout << t1+safeParamsBase_xOffset <<
", t, "
1584 << t2+safeParamsBase_xOffset <<
", t, ";
1586 std::cout <<
"'-' using ($1):($2) title \"control polygon\" with lp, "
1587 <<
"'-' using ($1):($2) title \"convex hull\" with lp";
1589 if(
i+1<
sizeof(someCurves)/
sizeof(
Bezier) )
1590 std::cout <<
",\\" << std::endl;
1592 std::cout << std::endl;
1594 safeParamsBase_xOffset += 2;
1597 safeParamsBase_xOffset = curr_Offset;
1598 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1602 c.
p0.
x += safeParamsBase_xOffset;
1603 c.
p1.
x += safeParamsBase_xOffset;
1604 c.
p2.
x += safeParamsBase_xOffset;
1605 c.
p3.
x += safeParamsBase_xOffset;
1620 for( k=0; k<poly.size(); ++k )
1622 std::cout << poly[k].x <<
" " << poly[k].y << std::endl;
1624 std::cout << poly[0].x <<
" " << poly[0].y << std::endl;
1625 std::cout <<
"e" << std::endl;
1627 for( k=0; k<convHull.size(); ++k )
1629 std::cout << convHull[k].x <<
" " << convHull[k].y << std::endl;
1631 std::cout << convHull[0].x <<
" " << convHull[0].y << std::endl;
1632 std::cout <<
"e" << std::endl;
1634 safeParamsBase_xOffset += 2;
1639#ifdef WITH_SAFEPARAMS_TEST
1641 const double safeParams_xOffset( curr_Offset );
1643 std::cout <<
"# safe param range testing" << std::endl
1644 <<
"plot [t=0.0:1.0] ";
1645 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1647 for( j=
i+1; j<
sizeof(someCurves)/
sizeof(
Bezier); ++j )
1650 Bezier c2( someCurves[j] );
1652 c1.
p0.
x += safeParams_xOffset;
1653 c1.
p1.
x += safeParams_xOffset;
1654 c1.
p2.
x += safeParams_xOffset;
1655 c1.
p3.
x += safeParams_xOffset;
1656 c2.
p0.
x += safeParams_xOffset;
1657 c2.
p1.
x += safeParams_xOffset;
1658 c2.
p2.
x += safeParams_xOffset;
1659 c2.
p3.
x += safeParams_xOffset;
1677 std::cout <<
" bez("
1681 << c1.
p3.
x <<
",t),bez("
1685 << c1.
p3.
y <<
",t), bez("
1689 << c2.
p3.
x <<
",t),bez("
1693 << c2.
p3.
y <<
",t), bez("
1694 << c1_part1.
p0.
x <<
","
1695 << c1_part1.
p1.
x <<
","
1696 << c1_part1.
p2.
x <<
","
1697 << c1_part1.
p3.
x <<
",t),bez("
1698 << c1_part1.
p0.
y <<
","
1699 << c1_part1.
p1.
y <<
","
1700 << c1_part1.
p2.
y <<
","
1701 << c1_part1.
p3.
y <<
",t)";
1703 if(
i+2<
sizeof(someCurves)/
sizeof(
Bezier) )
1704 std::cout <<
",\\" << std::endl;
1706 std::cout << std::endl;
1712#ifdef WITH_SAFEPARAM_DETAILED_TEST
1714 const double safeParams2_xOffset( curr_Offset );
1716 if(
sizeof(someCurves)/
sizeof(
Bezier) > 1 )
1718 Bezier c1( someCurves[0] );
1719 Bezier c2( someCurves[1] );
1721 c1.
p0.
x += safeParams2_xOffset;
1722 c1.
p1.
x += safeParams2_xOffset;
1723 c1.
p2.
x += safeParams2_xOffset;
1724 c1.
p3.
x += safeParams2_xOffset;
1725 c2.
p0.
x += safeParams2_xOffset;
1726 c2.
p1.
x += safeParams2_xOffset;
1727 c2.
p2.
x += safeParams2_xOffset;
1728 c2.
p3.
x += safeParams2_xOffset;
1737#ifdef WITH_SAFEFOCUSPARAM_TEST
1739 const double safeParamsFocus_xOffset( curr_Offset );
1741 std::cout <<
"# safe param range from focus testing" << std::endl
1742 <<
"plot [t=0.0:1.0] ";
1743 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1745 for( j=
i+1; j<
sizeof(someCurves)/
sizeof(
Bezier); ++j )
1748 Bezier c2( someCurves[j] );
1750 c1.
p0.
x += safeParamsFocus_xOffset;
1751 c1.
p1.
x += safeParamsFocus_xOffset;
1752 c1.
p2.
x += safeParamsFocus_xOffset;
1753 c1.
p3.
x += safeParamsFocus_xOffset;
1754 c2.
p0.
x += safeParamsFocus_xOffset;
1755 c2.
p1.
x += safeParamsFocus_xOffset;
1756 c2.
p2.
x += safeParamsFocus_xOffset;
1757 c2.
p3.
x += safeParamsFocus_xOffset;
1762#ifdef WITH_SAFEFOCUSPARAM_CALCFOCUS
1795 std::cerr <<
"t1: " << t1 <<
", t2: " << t2 << std::endl;
1809 std::cout <<
" bez("
1813 << c1.
p3.
x <<
",t),bez("
1817 << c1.
p3.
y <<
",t) title \"c1\", "
1818#ifdef WITH_SAFEFOCUSPARAM_CALCFOCUS
1823 << c2.
p3.
x <<
",t),bez("
1827 << c2.
p3.
y <<
",t) title \"c2\", "
1829 << focus.
p0.
x <<
","
1830 << focus.
p1.
x <<
","
1831 << focus.
p2.
x <<
","
1832 << focus.
p3.
x <<
",t),bez("
1833 << focus.
p0.
y <<
","
1834 << focus.
p1.
y <<
","
1835 << focus.
p2.
y <<
","
1836 << focus.
p3.
y <<
",t) title \"focus\"";
1842 << c2.
p3.
x <<
",t),bez("
1846 << c2.
p3.
y <<
",t) title \"focus\"";
1850 std::cout <<
", bez("
1851 << c1_part1.
p0.
x <<
","
1852 << c1_part1.
p1.
x <<
","
1853 << c1_part1.
p2.
x <<
","
1854 << c1_part1.
p3.
x <<
",t),bez("
1855 << c1_part1.
p0.
y+0.01 <<
","
1856 << c1_part1.
p1.
y+0.01 <<
","
1857 << c1_part1.
p2.
y+0.01 <<
","
1858 << c1_part1.
p3.
y+0.01 <<
",t) title \"part\"";
1861 if(
i+2<
sizeof(someCurves)/
sizeof(
Bezier) )
1862 std::cout <<
",\\" << std::endl;
1864 std::cout << std::endl;
1869#ifdef WITH_SAFEFOCUSPARAM_DETAILED_TEST
1871 const double safeParams3_xOffset( curr_Offset );
1873 if(
sizeof(someCurves)/
sizeof(
Bezier) > 1 )
1875 Bezier c1( someCurves[0] );
1876 Bezier c2( someCurves[1] );
1878 c1.
p0.
x += safeParams3_xOffset;
1879 c1.
p1.
x += safeParams3_xOffset;
1880 c1.
p2.
x += safeParams3_xOffset;
1881 c1.
p3.
x += safeParams3_xOffset;
1882 c2.
p0.
x += safeParams3_xOffset;
1883 c2.
p1.
x += safeParams3_xOffset;
1884 c2.
p2.
x += safeParams3_xOffset;
1885 c2.
p3.
x += safeParams3_xOffset;
1890#ifdef WITH_SAFEFOCUSPARAM_CALCFOCUS
1902#ifdef WITH_BEZIERCLIP_TEST
1903 std::vector< std::pair<double, double> >
result;
1904 std::back_insert_iterator< std::vector< std::pair<double, double> > > ii(
result);
1907 const double bezierClip_xOffset( curr_Offset );
1908 std::cout << std::endl << std::endl <<
"# bezier clip testing" << std::endl
1910 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1912 for( j=
i+1; j<
sizeof(someCurves)/
sizeof(
Bezier); ++j )
1915 Bezier c2( someCurves[j] );
1917 c1.
p0.
x += bezierClip_xOffset;
1918 c1.
p1.
x += bezierClip_xOffset;
1919 c1.
p2.
x += bezierClip_xOffset;
1920 c1.
p3.
x += bezierClip_xOffset;
1921 c2.
p0.
x += bezierClip_xOffset;
1922 c2.
p1.
x += bezierClip_xOffset;
1923 c2.
p2.
x += bezierClip_xOffset;
1924 c2.
p3.
x += bezierClip_xOffset;
1926 std::cout <<
" bez("
1930 << c1.
p3.
x <<
",t),bez("
1934 << c1.
p3.
y <<
",t), bez("
1938 << c2.
p3.
x <<
",t),bez("
1942 << c2.
p3.
y <<
",t), '-' using (bez("
1951 << c1.
p3.
y <<
",$1)) title \"bezier " <<
i <<
" clipped against " << j <<
" (t on " <<
i <<
")\", "
1952 <<
" '-' using (bez("
1961 << c2.
p3.
y <<
",$1)) title \"bezier " <<
i <<
" clipped against " << j <<
" (t on " << j <<
")\"";
1963 if(
i+2<
sizeof(someCurves)/
sizeof(
Bezier) )
1964 std::cout <<
",\\" << std::endl;
1966 std::cout << std::endl;
1969 for(
i=0;
i<
sizeof(someCurves)/
sizeof(
Bezier); ++
i )
1971 for( j=
i+1; j<
sizeof(someCurves)/
sizeof(
Bezier); ++j )
1975 Bezier c2( someCurves[j] );
1977 c1.
p0.
x += bezierClip_xOffset;
1978 c1.
p1.
x += bezierClip_xOffset;
1979 c1.
p2.
x += bezierClip_xOffset;
1980 c1.
p3.
x += bezierClip_xOffset;
1981 c2.
p0.
x += bezierClip_xOffset;
1982 c2.
p1.
x += bezierClip_xOffset;
1983 c2.
p2.
x += bezierClip_xOffset;
1984 c2.
p3.
x += bezierClip_xOffset;
1988 for( k=0; k<
result.size(); ++k )
1990 std::cout <<
result[k].first << std::endl;
1992 std::cout <<
"e" << std::endl;
1994 for( k=0; k<
result.size(); ++k )
1996 std::cout <<
result[k].second << std::endl;
1998 std::cout <<
"e" << std::endl;
void printCurvesWithSafeRange(const Bezier &c1, const Bezier &c2, double t1_c1, double t2_c1, const Bezier &c2_part, const FatLine &bounds_c2)
bool Impl_calcClipRange(double &t1, double &t2, const Bezier &c1_orig, const Bezier &c1_part, const Bezier &c2_orig, const Bezier &c2_part)
determine parameter ranges [0,t1) and (t2,1] on c1, where c1 is guaranteed to lie outside c2.
int fallFac(int n, int k)
void Impl_calcFocus(Bezier &res, const Bezier &c)
bool Impl_doBBoxIntersect(const Bezier &c1, const Bezier &c2)
void clipBezier(std::back_insert_iterator< std::vector< std::pair< double, double > > > &result, double delta, const Bezier &c1, const Bezier &c2)
Perform a bezier clip (curve against curve)
void Impl_deCasteljauAt(Bezier &part1, Bezier &part2, const Bezier &input, double t)
void Impl_calcFatLine(FatLine &line, const Bezier &c)
void printResultWithFinalCurves(const Bezier &c1, const Bezier &c1_part, const Bezier &c2, const Bezier &c2_part, double t1_c1, double t2_c1)
bool Impl_calcSafeParams_clip(double &t1, double &t2, const FatLine &bounds, double c0, double c1, double c2, double c3)
void Impl_calcBounds(Point2D &leftTop, Point2D &rightBottom, const Bezier &c1)
void Impl_applySafeRanges_rec(std::back_insert_iterator< std::vector< std::pair< double, double > > > &result, double delta, const Functor &safeRangeFunctor, int recursionLevel, const Bezier &c1_orig, const Bezier &c1_part, double last_t1_c1, double last_t2_c1, const Bezier &c2_orig, const Bezier &c2_part, double last_t1_c2, double last_t2_c2)
Calc all values t_i on c1, for which safeRanges functor does not give a safe range on c1 and c2.
int main(int argc, const char *argv[])
bool Impl_calcSafeParams_focus(double &t1, double &t2, const Bezier &curve, const Bezier &focus)
bool Impl_calcSafeParams(double &t1, double &t2, const Polygon2D &rPoly, double lowerYBound, double upperYBound)
DataType calcLineDistance(const DataType &a, const DataType &b, const DataType &c, const DataType &x, const DataType &y)
bool tolEqual(NumType n1, NumType n2)
Polygon2D convexHull(const Polygon2D &rPoly)
bool tolGreaterEqual(NumType n1, NumType n2)
bool tolLessEqual(NumType n1, NumType n2)
std::vector< Point2D > Polygon2D
bool solve(Matrix &matrix, int rows, int cols, Vector &result, BaseType minPivot)
This method determines solution of given linear system, if any.
constexpr OUStringLiteral first
bool operator()(double &t1_c1, double &t2_c1, const Bezier &c1_orig, const Bezier &c1_part, const Bezier &c2_orig, const Bezier &c2_part) const
bool operator()(double &t1_c1, double &t2_c1, const Bezier &c1_orig, const Bezier &c1_part, const Bezier &c2_orig, const Bezier &c2_part) const