20 double signx = ( f[
X].
at0() > f[
X].
at1() )? -1 : 1;
21 double signy = ( f[
Y].
at0() > f[
Y].
at1() )? -1 : 1;
29 bot.
cuts.insert( bot.
cuts.begin(), - 1 );
32 top +=
Point(-tol*signx, tol);
33 bot +=
Point( tol*signx, -tol);
36 std::swap( top, bot );
37 top +=
Point( 0, 2*tol);
38 bot +=
Point( 0, -2*tol);
74 std::vector<Interval>
result;
78 std::vector<double> someroots;
79 std::vector<double> cuts (2,0.);
83 cuts.insert( cuts.end(), someroots.begin(), someroots.end() );
86 cuts.insert( cuts.end(), someroots.begin(), someroots.end() );
90 cuts.insert( cuts.end(), someroots.begin(), someroots.end() );
93 cuts.insert( cuts.end(), someroots.begin(), someroots.end() );
95 sort(cuts.begin(),cuts.end());
96 unique(cuts.begin(), cuts.end() );
98 for (
unsigned i=1; i<cuts.size(); i++){
118 if ( f.
size() == 0 )
return;
119 f.
cuts.insert( f.
cuts.begin(), f.
cuts.front() - paddle_width );
121 f.
cuts.insert( f.
cuts.end(), f.
cuts.back() + paddle_width );
135 for (
unsigned i=0; i < inters.size(); i++ ){
136 for (
unsigned j=i+1; j < inters.size() && inters[i].times[
X].
intersects( inters[j].times[
X]) ; j++ ){
137 if (inters[i].times[
Y].
intersects( inters[j].times[
Y] ) ){
138 inters[i].times.unionWith(inters[j].times);
139 inters[i].bbox.unionWith(inters[j].bbox);
140 inters.erase( inters.begin() + j );
149std::vector<Interval>
intersect( std::vector<Interval>
const &a, std::vector<Interval>
const &b){
150 std::vector<Interval>
result;
176 bool swapresult =
false;
177 bool swapcoord =
false;
182 if ( !abounds || !bbounds )
return std::vector<SmashIntersection>();
183 abounds->expandBy(tol);
185 return std::vector<SmashIntersection>();
191 if ( dbbounds->min().length() > dabounds->min().length() ){
194 swap( dabounds, dbbounds );
199 double dxmin = std::min( std::abs((*dabounds)[
X].
max()), std::abs((*dabounds)[
X].
min()) );
200 double dymin = std::min( std::abs((*dabounds)[
Y].
max()), std::abs((*dabounds)[
Y].
min()) );
201 if ( (*dabounds)[
X].
max()*(*dabounds)[
X].
min() < 0 ) dxmin=0;
202 if ( (*dabounds)[
Y].
max()*(*dabounds)[
Y].
min() < 0 ) dymin=0;
203 assert (dxmin>=0 && dymin>=0);
212 Interval x_range_strict( aa[
X].at0(), aa[
X].at1() );
220 std::vector<Interval> bx_in_ax_range =
level_set(bb[
X], ax_range );
223 std::vector<Interval> tbs;
224 for (
auto & i : bx_in_ax_range){
228 bb_in[
X].setDomain( i );
229 bb_in[
Y].setDomain( i );
233 h = bb_in[
Y] -
compose( top_ay, bb_in[
X] );
235 std::vector<Interval> rts_lo =
level_set( h, level);
236 h = bb_in[
Y] -
compose( bot_ay, bb_in[
X] );
238 std::vector<Interval> rts_hi =
level_set( h, level);
240 std::vector<Interval> rts =
intersect( rts_lo, rts_hi );
241 tbs.insert(tbs.end(), rts.begin(), rts.end() );
253 for (
unsigned j=0; j<tbs.size(); j++){
255 std::vector<Interval> tas;
266 h = top_b[
Y] -
compose( fat_y_of_x, top_b[
X] );
268 std::vector<Interval> rts_top =
level_set( h, level);
269 for (
auto & idx : rts_top){
270 idx =
Interval( top_b[
X].valueAt( idx.min() ),
273 assert( rts_top.size() == 1 );
275 h = bot_b[
Y] -
compose( fat_y_of_x, bot_b[
X] );
277 std::vector<Interval> rts_bot =
level_set( h, level);
278 for (
auto & idx : rts_bot){
279 idx =
Interval( bot_b[
X].valueAt( idx.min() ),
282 assert( rts_bot.size() == 1 );
284 assert (rts_top.size() == 1);
287 if ( x_dom.
max() <= x_range_strict.
min() ){
288 tas.push_back(
Interval ( ( aa[
X].at0() < aa[
X].at1() ) ? 0 : 1 ) );
289 }
else if ( x_dom.
min() >= x_range_strict.
max() ){
290 tas.push_back(
Interval ( ( aa[
X].at0() < aa[
X].at1() ) ? 1 : 0 ) );
294 assert( tas.size()==1 );
295 result[j].times[
X] = tas.front();
299 result[j].bbox.unionWith(
Rect( x_dom, y_dom ) );
304 swap( i.times[
X], i.times[
Y]);
309 swap( i.bbox[
X], i.bbox[
Y] );
318 std::vector<SmashIntersection>
result;
322 for (
auto & acut : acuts){
324 for (
auto & bcut : bcuts){
327 for (
auto & k : ai_cap_bj){
328 k.times[
X] = k.times[
X] * acut.extent() + acut.min();
329 k.times[
Y] = k.times[
Y] * bcut.extent() + bcut.min();
331 result.insert(
result.end(), ai_cap_bj.begin(), ai_cap_bj.end() );
Adaptor that creates 2D functions from 1D ones.
Point valueAt(double t) const
bool intersects(CRect const &r) const
Check whether the rectangles have any common points.
CPoint min() const
Get the corner of the rectangle with smallest coordinate values.
Range of real numbers that is never empty.
Function that interpolates linearly between two values.
Range of real numbers that can be empty.
Axis-aligned rectangle that can be empty.
Function defined as discrete pieces.
void offsetDomain(double o)
output_type lastValue() const
std::vector< double > cuts
output_type firstValue() const
Two-dimensional point that doubles as a vector.
Axis aligned, non-empty rectangle.
Polynomial in symmetric power basis.
Lifts one dimensional objects into 2D.
constexpr Coord infinity()
Get a value representing infinity.
Various utility functions.
D2< Piecewise< SBasis > > make_cuts_independent(Piecewise< D2< SBasis > > const &a)
OptInterval bounds_exact(Bezier const &b)
MultiDegree< n > max(MultiDegree< n > const &p, MultiDegree< n > const &q)
Returns the maximal degree appearing in the two arguments for each variables.
static void computeLinfinityNeighborhood(D2< SBasis > const &f, double tol, D2< Piecewise< SBasis > > &topside, D2< Piecewise< SBasis > > &botside)
std::vector< SmashIntersection > smash_intersect(D2< SBasis > const &a, D2< SBasis > const &b, double tol)
static void prolongateByConstants(Piecewise< SBasis > &f, double paddle_width)
D2< T > compose(D2< T > const &a, T const &b)
std::vector< double > roots(SBasis const &s)
static bool compareIntersectionsTimesX(SmashIntersection const &inter1, SmashIntersection const &inter2)
std::vector< SmashIntersection > monotonic_smash_intersect(D2< SBasis > const &a, D2< SBasis > const &b, double tol)
static void cleanup_and_fuse(std::vector< SmashIntersection > &inters)
Bezier portion(const Bezier &a, double from, double to)
Bezier derivative(Bezier const &a)
Piecewise< SBasis > pw_compose_inverse(SBasis const &f, SBasis const &g, unsigned order, double zero)
Piecewise< SBasis > min(SBasis const &f, SBasis const &g)
Return the more negative of the two functions pointwise.
std::vector< Interval > monotonicSplit(D2< SBasis > const &p)
OptInterval bounds_fast(Bezier const &b)
std::vector< Point > intersect(const xAx &C1, const xAx &C2)
std::vector< Interval > level_set(D2< SBasis > const &f, Rect region)
two-dimensional geometric operators.
Polynomial in symmetric power basis (S-basis)