28 #ifndef __ETL__SURFACE_H
29 #define __ETL__SURFACE_H
44 template <
typename T,
typename AT>
55 template <
typename T,
typename AT=T,
class VP=value_prep<T,AT> >
136 template <
typename _pen>
139 typename _pen::difference_type
size=_end-_begin;
152 (*
this)[y][x]=_begin.get_value_at(x,y);
259 if(w<=0 || h<=0)
return;
267 template <
class _pen>
void
271 if(w<=0 || h<=0)
return;
274 for(y=0;y<h;y++,PEN.inc_y(),PEN.dec_x(w))
292 template <
class _pen>
void
294 int x,
int y,
int w,
int h)
313 w = std::min((
long)w,(
long)(DEST_PEN.end_x()-DEST_PEN.x()));
314 h = std::min((
long)h,(
long)(DEST_PEN.end_y()-DEST_PEN.y()));
317 w = std::min(w,
w_-x);
318 h = std::min(h,
h_-y);
325 for(; h>0; h--,DEST_PEN.inc_y(),SOURCE_PEN.
inc_y())
328 for(i=0; i<w; i++,DEST_PEN.inc_x(),SOURCE_PEN.
inc_x())
330 DEST_PEN.put_value(SOURCE_PEN.
get_value());
390 static const float epsilon(1.0e-6);
392 if(x<0.0
f)u=0,a=0.0f;
393 else if(x>
w_-1)u=
w_-1,a=0.0f;
396 if(y<0.0
f)v=0,b=0.0f;
397 else if(y>
h_-1)v=
h_-1,b=0.0f;
401 c(1.0
f-a), d(1.0
f-b),
402 e(a*d),
f(c*b),g(a*b);
405 if(e>=epsilon)ret+=
cooker_.cook((*
this)[v][u+1])*e;
406 if(
f>=epsilon)ret+=
cooker_.cook((*
this)[v+1][u])*
f;
407 if(g>=epsilon)ret+=
cooker_.cook((*
this)[v+1][u+1])*g;
414 #define h(j,i) (((accumulator_type)((*this)[j][i])))
417 static const float epsilon(1.0e-6);
419 if(x<0.0
f)u=0,a=0.0f;
420 else if(x>
w_-1)u=
w_-1,a=0.0f;
423 if(y<0.0
f)v=0,b=0.0f;
424 else if(y>
h_-1)v=
h_-1,b=0.0f;
428 c(1.0
f-a), d(1.0
f-b),
429 e(a*d),
f(c*b),g(a*b);
432 if(e>=epsilon)ret+=
h(v,u+1)*e;
433 if(
f>=epsilon)ret+=
h(v+1,u)*
f;
434 if(g>=epsilon)ret+=
h(v+1,u+1)*g;
445 static const float epsilon(1.0e-6);
447 if(x<0.0
f)u=0,a=0.0f;
448 else if(x>
w_-1)u=
w_-1,a=0.0f;
451 if(y<0.0
f)v=0,b=0.0f;
452 else if(y>
h_-1)v=
h_-1,b=0.0f;
455 a=(1.0f-
cos(a*3.1415927
f))*0.5f;
456 b=(1.0f-
cos(b*3.1415927f))*0.5f;
459 c(1.0f-a), d(1.0f-b),
460 e(a*d),f(c*b),g(a*b);
463 if(e>=epsilon)ret+=
cooker_.cook((*
this)[v][u+1])*e;
464 if(f>=epsilon)ret+=
cooker_.cook((*
this)[v+1][u])*f;
465 if(g>=epsilon)ret+=
cooker_.cook((*
this)[v+1][u+1])*g;
473 #define h(j,i) (((accumulator_type)((*this)[j][i])))
477 static const float epsilon(1.0e-6);
479 if(x<0.0
f)u=0,a=0.0f;
480 else if(x>
w_-1)u=
w_-1,a=0.0f;
483 if(y<0.0
f)v=0,b=0.0f;
484 else if(y>
h_-1)v=
h_-1,b=0.0f;
487 a=(1.0f-
cos(a*3.1415927
f))*0.5f;
488 b=(1.0f-
cos(b*3.1415927f))*0.5f;
491 c(1.0f-a), d(1.0f-b),
492 e(a*d),f(c*b),g(a*b);
495 if(e>=epsilon)ret+=
h(v,u+1)*e;
496 if(f>=epsilon)ret+=
h(v+1,u)*f;
497 if(g>=epsilon)ret+=
h(v+1,u+1)*g;
507 #define P(x) (((x)>=0)?((x)*(x)*(x)):0.0f)
508 #define R(x) ( P(x+2) - 4.0f*P(x+1) + 6.0f*P(x) - 4.0f*P(x-1) )*(1.0f/6.0f)
509 #define F(i,j) (cooker_.cook((*this)[max(min(j+v,h_-1),0)][max(min(i+u,w_-1),0)])*(R((i)-a)*R(b-(j))))
510 #define Z(i,j) ret+=F(i,j)
511 #define X(i,j) // placeholder... To make box more symmetric
517 if(x<0.0
f)u=0,a=0.0f;
518 else if(u>
w_-1)u=
w_-1,a=0.0f;
522 if(y<0.0
f)v=0,b=0.0f;
523 else if(v>
h_-1)v=
h_-1,b=0.0f;
528 Z(-1,-1); Z(-1, 0); Z(-1, 1); Z(-1, 2);
529 Z( 0,-1); X( 0, 0); Z( 0, 1); Z( 0, 2);
530 Z( 1,-1); Z( 1, 0); Z( 1, 1); Z( 1, 2);
531 Z( 2,-1); Z( 2, 0); Z( 2, 1); Z( 2, 2);
542 #define f(j,i) (cooker_.cook((*this)[j][i]))
548 const int xi = x > 0 ? (x <
w_ ? (int)
floor(x) : w_-1) : 0;
549 const int xa[] = {std::max(0,xi-1),xi,std::min(w_-1,xi+1),std::min(w_-1,xi+2)};
551 const int yi = y > 0 ? (y <
h_ ? (int)
floor(y) : h_-1) : 0;
552 const int ya[] = {std::max(0,yi-1),yi,std::min(h_-1,yi+1),std::min(h_-1,yi+2)};
554 const float xf = x-xi;
555 const float yf = y-yi;
560 0.5f*xf*(xf*(xf*(-1.f) + 2.
f) - 1.f),
561 0.5
f*(xf*(xf*(3.
f*xf - 5.
f)) + 2.
f),
562 0.5f*xf*(xf*(-3.f*xf + 4.f) + 1.
f),
568 0.5f*yf*(yf*(yf*(-1.f) + 2.
f) - 1.f),
569 0.5
f*(yf*(yf*(3.
f*yf - 5.
f)) + 2.
f),
570 0.5f*yf*(yf*(-3.f*yf + 4.f) + 1.
f),
575 for(
int i = 0; i < 4; ++i)
577 xfa[i] =
f(ya[i],xa[0])*txf[0] +
f(ya[i],xa[1])*txf[1] +
f(ya[i],xa[2])*txf[2] +
f(ya[i],xa[3])*txf[3];
581 return cooker_.uncook(xfa[0]*tyf[0] + xfa[1]*tyf[1] + xfa[2]*tyf[2] + xfa[3]*tyf[3]);
589 #define f(j,i) (((accumulator_type)((*this)[j][i])))
595 const int xi = x > 0 ? (x < w_ ? (int)
floor(x) : w_-1) : 0;
596 const int xa[] = {std::max(0,xi-1),xi,std::min(w_-1,xi+1),std::min(w_-1,xi+2)};
598 const int yi = y > 0 ? (y < h_ ? (int)
floor(y) : h_-1) : 0;
599 const int ya[] = {std::max(0,yi-1),yi,std::min(h_-1,yi+1),std::min(h_-1,yi+2)};
601 const float xf = x-xi;
602 const float yf = y-yi;
607 0.5f*xf*(xf*(xf*(-1) + 2) - 1),
608 0.5
f*(xf*(xf*(3*xf - 5)) + 2),
609 0.5f*xf*(xf*(-3*xf + 4) + 1),
615 0.5f*yf*(yf*(yf*(-1.f) + 2.
f) - 1.f),
616 0.5
f*(yf*(yf*(3.
f*yf - 5.
f)) + 2.
f),
617 0.5f*yf*(yf*(-3.f*yf + 4.f) + 1.
f),
622 for(
int i = 0; i < 4; ++i)
624 xfa[i] =
f(ya[i],xa[0])*txf[0] +
f(ya[i],xa[1])*txf[1] +
f(ya[i],xa[2])*txf[2] +
f(ya[i],xa[3])*txf[3];
628 return (
value_type)(xfa[0]*tyf[0] + xfa[1]*tyf[1] + xfa[2]*tyf[2] + xfa[3]*tyf[3]);
647 int xib=(int)
floor(x0),
650 int yib=(int)
floor(y0),
654 float weight = (y1-y0)*(x1-x0);
657 float ylast = y0, xlastb = x0;
660 for(yi = yib; yi < yie; ylast = ++yi, pen_.
inc_y())
662 const float yweight = yi+1 - ylast;
664 float xlast = xlastb;
665 for(xi = xib; xi < xie; xlast = ++xi, pen_.
inc_x())
667 const float w = yweight*(xi+1 - xlast);
672 const float w = yweight*(x1 - xlast);
680 const float yweight = y1 - ylast;
682 float xlast = xlastb;
683 for(xi = xib; xi < xie; xlast = ++xi)
685 const float w = yweight*(xi+1 - xlast);
691 const float w = yweight*(x1 - xlast);
714 int xib=(int)
floor(x0),
717 int yib=(int)
floor(y0),
721 float weight = (y1-y0)*(x1-x0);
724 float ylast = y0, xlastb = x0;
727 for(yi = yib; yi < yie; ylast = ++yi, pen_.
inc_y())
729 const float yweight = yi+1 - ylast;
731 float xlast = xlastb;
732 for(xi = xib; xi < xie; xlast = ++xi, pen_.
inc_x())
734 const float w = yweight*(xi+1 - xlast);
739 const float w = yweight*(x1 - xlast);
747 const float yweight = y1 - ylast;
749 float xlast = xlastb;
750 for(xi = xib; xi < xie; xlast = ++xi)
752 const float w = yweight*(xi+1 - xlast);
758 const float w = yweight*(x1 - xlast);
781 int xib=(int)
floor(x0),
784 int yib=(int)
floor(y0),
788 float weight = (y1-y0)*(x1-x0);
793 if(x0 >= s.
get_w() || x1 <= 0)
return acum;
794 if(y0 >= s.
get_h() || y1 <= 0)
return acum;
796 if(x0 < 0) { x0 = 0; xib = 0; }
803 if(y0 < 0) { y0 = 0; yib = 0; }
810 float ylast = y0, xlastb = x0;
813 for(yi = yib; yi < yie; ylast = ++yi, pen.
inc_y())
815 const float yweight = yi+1 - ylast;
817 float xlast = xlastb;
818 for(xi = xib; xi < xie; xlast = ++xi, pen.
inc_x())
820 const float w = yweight*(xi+1 - xlast);
825 const float w = yweight*(x1 - xlast);
833 const float yweight = y1 - ylast;
835 float xlast = xlastb;
836 for(xi = xib; xi < xie; xlast = ++xi)
838 const float w = yweight*(xi+1 - xlast);
844 const float w = yweight*(x1 - xlast);
867 int xib=(int)
floor(x0),
870 int yib=(int)
floor(y0),
874 float weight = (y1-y0)*(x1-x0);
879 if(x0 >= s.
get_w() || x1 <= 0)
return acum;
880 if(y0 >= s.
get_h() || y1 <= 0)
return acum;
882 if(x0 < 0) { x0 = 0; xib = 0; }
889 if(y0 < 0) { y0 = 0; yib = 0; }
896 float ylast = y0, xlastb = x0;
899 for(yi = yib; yi < yie; ylast = ++yi, pen.
inc_y())
901 const float yweight = yi+1 - ylast;
903 float xlast = xlastb;
904 for(xi = xib; xi < xie; xlast = ++xi, pen.
inc_x())
906 const float w = yweight*(xi+1 - xlast);
911 const float w = yweight*(x1 - xlast);
919 const float yweight = y1 - ylast;
921 float xlast = xlastb;
922 for(xi = xib; xi < xie; xlast = ++xi)
924 const float w = yweight*(xi+1 - xlast);
930 const float w = yweight*(x1 - xlast);