Skip to main content
Inspiring
August 4, 2013
Question

transform_world problem

  • August 4, 2013
  • 1 reply
  • 1637 views

Hi

I'm trying to use transform_world to take on world, scale it and translate it and copy it into the output

It seems that just scaling it and copying it works, and just translating it and copying it works, but trying do do both results in some really odd clipping/masking problem. The example code below should scale by a factor of 100 and then translate by 2 pixels in the x direction (unless I've messed up my matrix multiplication, but I don't think I have). As far as I can tell, both the scaling and the translation are working as they should, but in addition the copied image is cropped on the left. The attached images show the results if I use values of xtranslate of 2 and 2.5 pixels. In this case the world that is being copied from contains white noise, and that copied to is just a purple background. The crop amount seems to be (1-xtranslate)*scale, so is 100 for xtranslate of 2 and 150 for xtranslate of 2.5.

Does anyone have any idea of what is going on?

PF_CompositeMode mode;

mode.opacity=255;

mode.opacitySu=32768;

mode.rgb_only=false;

mode.xfer=PF_Xfer_IN_FRONT;

PF_FloatMatrix mat;

double ratio=(double)in_data->downsample_x.num/(double)in_data->downsample_x.den;

double scale=100.0*ratio;

double xtranslate=2.5*ratio;

mat.mat[0][0]=scale;

mat.mat[0][1]=0.0;

mat.mat[0][2]=0.0;

mat.mat[1][0]=0.0;

mat.mat[1][1]=scale;

mat.mat[1][2]=0.0;

mat.mat[2][0]=xtranslate*scale;

mat.mat[2][1]=0.0;

mat.mat[2][2]=scale;

PF_Rect dest;

dest.bottom=in_data->height;

dest.left=0;

dest.right=in_data->width;

dest.top=0;

int quality=PF_Quality_LO;

err=suites.WorldTransformSuite1()->transform_world(NULL,quality,0,PF_Field_FRAME,&ni.pixelworld,&mode,NULL,&mat,1,true,&dest,output);

links to examples

http://www.flickr.com/photos/78717189@N00/9437292828/

http://www.flickr.com/photos/78717189@N00/9434514543/

This topic has been closed for replies.

1 reply

Community Expert
August 4, 2013

hmmmm...

well, first, i'd go with PF_Quality_HI. no doubt some of the problems in the images you psted come from that.

secondly, i think you should concatenate your scale and translate matrices. (take a look at the CCU sample)

take a look at this thread:

http://forums.adobe.com/message/1967376#1967376

mybe somthing there will ring a bell.

Inspiring
August 4, 2013

Thanks for the response. I tried using PF_Quality_HI, but it doesn't help. The clipping is still there and it also doesn't give the enlargening I want in this case as it tries to smooth between the pixels of the white noise.

I looked in CCU.cpp and there doesn't appear to be any mention of PF_FloatMatrix at all. am I looking in the right place?

I had seen that previous thread - and it was very informative at enabing me to get transform_world working at all as the documentation is shocking. However, I couldn't see anything to help me in this case.

Phil

Community Expert
August 4, 2013

oh my... it seems to not exist in the ccu sample in CS5 and up.

here's the code from the CS3 SDK:

static void

CCU_ConcatMatrix (

                                          const          PF_FloatMatrix          *src_matrixP,

                                          PF_FloatMatrix          *dst_matrixP)

{

          PF_FloatMatrix          tmp;

 

           PF_FpLong          tempF           =          0;

 

             for (register A_long iL = 0; iL < 3; iL++) {

                       for (register A_long jL = 0; jL < 3; jL++) {

                              tempF =          dst_matrixP->mat[iL][0] * src_matrixP->mat[0][jL] +

                              dst_matrixP->mat[iL][1] * src_matrixP->mat[1][jL] +

                              dst_matrixP->mat[iL][2] * src_matrixP->mat[2][jL];

 

                                tmp.mat[iL][jL] = tempF;

                    }

          }

          *dst_matrixP = tmp;

}

void

CCU_SetIdentityMatrix (

          PF_FloatMatrix *matrixP)

{

          matrixP->mat[0][0] =

          matrixP->mat[1][1] =

          matrixP->mat[2][2] = 1;

 

          matrixP->mat[0][1] =

          matrixP->mat[0][2] =

          matrixP->mat[1][0] =

          matrixP->mat[1][2] =

          matrixP->mat[2][0] =

          matrixP->mat[2][1] = 0;

}

PF_Err

CCU_ScaleMatrix (

          PF_FloatMatrix           *mP,

          PF_FpLong                     scaleX,

          PF_FpLong                     scaleY,

          PF_FpLong                     aboutX,

          PF_FpLong                     aboutY )

{

          PF_Err                              err = PF_Err_NONE;

          PF_FloatMatrix          scale;

 

          if (scaleX != 1.0 || scaleY != 1.0)

          {

 

                    scale.mat[0][0] = scaleX; 

                    scale.mat[0][1] = 0

                    scale.mat[0][2] = 0;

 

                    scale.mat[1][0] = 0;

                    scale.mat[1][1] = scaleY;

                    scale.mat[1][2] = 0;

 

                    scale.mat[2][0] = (1.0 - scaleX) * (aboutX);

                    scale.mat[2][1] = (1.0 - scaleY) * (aboutY);

                    scale.mat[2][2] = 1;

 

                    CCU_ConcatMatrix(&scale, mP);

          }

          return err;

}

PF_Err

CCU_RotateMatrixPlus (

          PF_FloatMatrix          *matrixP,

          PF_InData                    *in_data,

          PF_FpLong                    degreesF,

          PF_FpLong                    aboutXF,

          PF_FpLong                    aboutYF)

{

          AEGP_SuiteHandler          suites(in_data->pica_basicP);

 

          PF_Err                              err                     = PF_Err_NONE;

          PF_FloatMatrix          rotate;

          PF_FpLong                    radiansF          =          0,

                                                  sF                               =           0,

                                                  cF                               =           0;

 

          if (degreesF){

                    radiansF           =            PF_RAD_PER_DEGREE * degreesF;

                    sF                              =           suites.ANSICallbacksSuite1()->sin(radiansF);

                    cF                              =           suites.ANSICallbacksSuite1()->cos(radiansF);

 

                    rotate.mat[0][0] =          cF;

                    rotate.mat[0][1] =          sF;

                    rotate.mat[0][2] =          0;

 

                    rotate.mat[1][0] =          -sF;

                    rotate.mat[1][1] =          cF;

                    rotate.mat[1][2] =          0;

 

                    rotate.mat[2][0] =          (aboutXF * (1.0 - cF) + aboutYF * sF);

                    rotate.mat[2][1] =          (aboutYF * (1.0 - cF) - aboutXF * sF);

                    rotate.mat[2][2] =          1;

 

                    CCU_ConcatMatrix(&rotate, matrixP);

          }

          return err;

}

void

CCU_TransformFixPoints (

          const          PF_FloatMatrix          *matrixP,

                              A_long                              countL,

                              PF_FixedPoint          *pointsFiAP)

{

          PF_Fixed                              iL                                         =           0;

          PF_FixedPoint                    currentFiPt                    =          {0,0};

          PF_FpLong                              dF                                         =           0;

          for (iL = 0; iL < countL; iL++)

          {

 

                    currentFiPt          = pointsFiAP[iL];

                    dF                    =          currentFiPt.x * matrixP->mat[0][0] +

                                                  currentFiPt.y * matrixP->mat[1][0] +

                                                  65536.0 *

                                                  matrixP->mat[2][0];

 

                    pointsFiAP[iL].x          =           static_cast<PF_Fixed>(ROUND_DBL2LONG(dF));

 

                    dF                                                   =          currentFiPt.x * matrixP->mat[0][1] +

                                                                                currentFiPt.y *

                                                                                matrixP->mat[1][1] + 

                                                                                65536.0 *

                                                                                matrixP->mat[2][1];

                    pointsFiAP[iL].y          =          static_cast<PF_Fixed>(ROUND_DBL2LONG(dF));

          }

}

static void

TransformOval(

          PF_InData                              *in_data,

          PF_EventExtra                    *extra,

          PF_FixedRect                    *fx_frame,

          PF_Point                              *transformedPtP)

{

          AEGP_SuiteHandler          suites(in_data->pica_basicP);

 

          PF_FixedPoint                    centerFiPt          =          {0,0};

          PF_FloatMatrix                    mat;

          PF_FpLong                              angleF                     =           0,

                                                            dxF                              =          0,

                                                            dyF                              =           0,

                                                            x_radF                     =           0,

                                                            y_radF                     =           0;

          PF_FixedPoint                    copy_pts[OVAL_PTS];

 

          centerFiPt.x = (fx_frame->left           + fx_frame->right)           / 2;;

          centerFiPt.y = (fx_frame->top           + fx_frame->bottom) / 2;

          dxF = FIX_2_FLOAT(fx_frame->right - fx_frame->left);

          dyF = 0;

 

          angleF          =          suites.ANSICallbacksSuite1()->atan2(dyF, dxF);

          angleF           /=          PF_RAD_PER_DEGREE;

 

          x_radF = suites.ANSICallbacksSuite1()->sqrt(dxF * dxF + dyF * dyF) / 2.0;

          dxF          = 0;

          dyF          = FIX_2_FLOAT(fx_frame->bottom - fx_frame->top);

 

          y_radF          =          suites.ANSICallbacksSuite1()->sqrt(dxF * dxF + dyF * dyF) / 2.0;

          CCU_SetIdentityMatrix(&mat);

          CCU_ScaleMatrix(&mat,

                                                  x_radF,

                                                  y_radF,

                                                  0,

                                                  0);

          CCU_RotateMatrixPlus(          &mat,

                                                                      in_data,

                                                                      angleF,

                                                                      0,

                                                                      0);

          for (A_short iS = 0; iS < OVAL_PTS; iS++) {

                    copy_pts[iS].x = std_oval[iS].x;

                    copy_pts[iS].y = std_oval[iS].y;

          }

 

          CCU_TransformFixPoints(          &mat,

                                                                      OVAL_PTS,

                                                                      copy_pts);

 

          for (A_short jS = 0; jS < OVAL_PTS; jS++) {

                    copy_pts[jS].x += centerFiPt.x;

                    copy_pts[jS].y += centerFiPt.y;

          }

          for (A_short kS = 0; kS < OVAL_PTS; kS++) {

                    extra->cbs.layer_to_comp(          extra->cbs.refcon,

                                                                                          extra->contextH,

                                                                                          in_data->current_time,

                                                                                          in_data->time_scale,

                                                                                          (PF_FixedPoint *)&(copy_pts[kS]));

                    extra->cbs.source_to_frame( extra->cbs.refcon,

                                                                                          extra->contextH,

                                                                                          (PF_FixedPoint*)&(copy_pts[kS]));

          }

 

          for (A_short qS = 0; qS < OVAL_PTS; qS++) {

                    transformedPtP[qS].h = FIX2INT_ROUND(copy_pts[qS].x);

                    transformedPtP[qS].v = FIX2INT_ROUND(copy_pts[qS].y);

          }

}