Solved

How to use "SetWorldTransform"

Posted on 1998-09-17
15
733 Views
Last Modified: 2013-12-03
Hi!
I'm trying to rotate a metafile with the SetWorldTransform.
But it rotates around the upper left corner of my picture.
I want it to rotate around the center.
How do i do that ???
0
Comment
Question by:AndersCarlsson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
15 Comments
 
LVL 3

Expert Comment

by:danny_pav
ID: 1414530
how about setting the XFORM eDx and eDy to the point about which rotation occurs?
0
 

Author Comment

by:AndersCarlsson
ID: 1414531
Maybe some code could help ...

   hDC = BeginPaint( hWnd, (LPPAINTSTRUCT)&ps );

      /* Rita kursskivan som bakgrund till kompassen */
      SetMapMode( hDC, MM_ANISOTROPIC );


      SetViewportOrgEx( hDC, ClientRect.left, ClientRect.top, NULL );

      SetViewportExtEx( hDC, XSize, YSize, NULL );
      PlayMetaFile( hDC, hMFBackGround );

      /* Rita skillnadsfalt */
      if( Compass[ CpIx ]->Active ){
         SelectObject( hDC, YellowBrush );
      }
      else SelectObject( hDC, BlackBrush );

      SelectObject( hDC, GetStockObject( NULL_PEN ) );
      SetMapMode( hDC, MM_TEXT );

      /* Rita pie:n */
      Pie( hDC, Origo.x - DiffRadius, Origo.y - DiffRadius,
                Origo.x + DiffRadius, Origo.y + DiffRadius,
                Start.x, Start.y, Stop.x, Stop.y );

      /* Rita kompass nal */
      NeedleWidth = NeedleRect.right - NeedleRect.left;
      NeedleHight = NeedleRect.bottom - NeedleRect.top;

      SetMapMode( hDC, MM_ANISOTROPIC );

      SetViewportOrgEx( hDC, (int)(Origo.x - NeedleWidth/2.0),
         (int)(Origo.y - NeedleHight/2.0), NULL );


      SetViewportExtEx( hDC, NeedleWidth, NeedleHight, NULL );

      Rotation = (float)(Compass[ CpIx ]->ComCourse * DEGTORAD);

      NeedleXForm.eM11 = (float)cos( Rotation );
      NeedleXForm.eM12 = (float)sin( Rotation );
      NeedleXForm.eM21 = (float)-sin( Rotation );
      NeedleXForm.eM22 = (float)cos( Rotation );

      OldGraphMode = SetGraphicsMode( hDC, GM_ADVANCED );
     
      SetWorldTransform( hDC, &NeedleXForm );

      PlayMetaFile( hDC, hMFNeedle );

      SetGraphicsMode( hDC, OldGraphMode );
   EndPaint( hWnd, (LPPAINTSTRUCT)&ps );

0
 

Author Comment

by:AndersCarlsson
ID: 1414532
Thanks danny_pav

. but i've tried that and it doesnt work

any other suggestions ?
0
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now

 
LVL 15

Expert Comment

by:NickRepin
ID: 1414533
AndersCarlsson,
do you keep in mind that SetWorldTransform does not supported on Win 95 ?
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1414534
Use the eDx and eDy members of NeedleXForm to perform the horizontal and vertical translation (how much you want to move by).

danny_pav had this ...what's the effect of this
0
 

Author Comment

by:AndersCarlsson
ID: 1414535
NickRepin: I work on a NT machine.

Answers2000: I don't want to move the picture just rotate it.

If i set some values in eDx and eDy the picture moves to that position it seems (upper left corner). I want it to stay in center and rotate around the center of the metafile.
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1414536
Try to call SetViewportExt and SetViewportOrg again after calling SetGraphicsMode.
Also, I think it would be better to call SetWindowExt and SetWindowOrg along with viewport functions after changing map/graphics mode. At least, that's how I did it, and all worked fine.
0
 

Author Comment

by:AndersCarlsson
ID: 1414537
NickRepin
I´ve tried to call SetViewportExt and Org again after SetGraphicsMode and to set XFORM eDx and eDy to the center of my metafile. But that doesn´t help at all, it still rotates around the upper left corner. Probably i´ve made some misstake somewhere, but i can´t find it. I´ve increased the points to 150 cause this is important for me.
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1414538
World transformation doesn't depend on Window and Viewport settings. You should rotate like this:


   XFORM x1,x2,x3,result1,result2;
   
   // At first, move the center of the metafile in the center
   // of the world space
   x1.eDx=-center.x;  // Center of your metafile
   x1.eDy=-center.y;
   x1.eM11=1;x1.eM12=0;x1.eM21=0;x1.eM22=1;

   // Next, rotate around center of the world space
   x2.eDx=0;
   x2.eDy=0;
   x2.eM11=cos(Angle);
   x2.eM12=sin(Angle);
   x2.eM21=-sin(Angle);
   x2.eM22=cos(Angle);

   // The last, return metafile back in its place
   x3.eDx=center.x;
   x3.eDy=center.y;
   x3.eM11=1;x3.eM12=0;x3.eM21=0;x3.eM22=1;

   // Now do eral job
   CombineTransform(result1,&x1,&x2);
   CombineTransform(result2,&result1,&x3);
   SetWorldTransform(dc,&result2);

Good luck!

0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1414539
Type errors...

// Now do REAL job....
..

Minus is so little on screen:
  x1.eDX= - center.x
  x2.eDY= - center.y
0
 

Author Comment

by:AndersCarlsson
ID: 1414540
It didn´t work NickRepin.
My MetaFile still rotates around the upper left corner
My code is as follows:

      OldGraphMode = SetGraphicsMode( hDC, GM_ADVANCED );

      SetViewportOrgEx( hDC, (int)(Origo.x - NeedleWidth/2.0),
         (int)(Origo.y - NeedleHight/2.0), NULL );
      SetViewportExtEx( hDC, NeedleWidth, NeedleHight, NULL );

        Pivot.x = (int)(NeedleWidth/2.0);
        Pivot.y = (int)(NeedleHight/2.0);

     
        // At first move the center of the metafile
        // in the center of the world space
        x1.eDx = -Pivot.x;
        x1.eDy = -Pivot.y;
        x1.eM11 = 1;
        x1.eM12 = 0;
        x1.eM21 = 0;
        x1.eM22 = 1;

        // Next rotate around center of world space
        x2.eDx = 0;
        x2.eDy = -Pivot.y;
        x2.eM11 = (float)cos( Rotation );
        x2.eM12 = (float)sin( Rotation );
        x2.eM21 = (float)-sin( Rotation );
        x2.eM22 = (float)cos( Rotation );

        // The last, return metafile back in its place
        x3.eDx = Pivot.x;
        x3.eDy = Pivot.y;
        x3.eM11 = 1;
        x3.eM12 = 0;
        x3.eM21 = 0;
        x3.eM22 = 1;

        // Now do real job
      CombineTransform(&result1, &x1, &x2 );
      CombineTransform(&result2, &result1, &x3 );

      SetWorldTransform( hDC, &result2 );

      PlayMetaFile( hDC, hMFNeedle );

      SetGraphicsMode( hDC, OldGraphMode );

   /* Avsluta uppdatering av klientarean */
   EndPaint( hWnd, (LPPAINTSTRUCT)&ps );


Whats wrong i think you can help me if you can ther´s another 100 points there for you.

0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1414541
1) x2.eDY must be 0
-------------------
2) Check result of SetGraphicsMode(GM_ADVANCED)
0
 

Author Comment

by:AndersCarlsson
ID: 1414542
OK!
1) I just followed your "Type error" comment.
2) SetGraphicsMode result is nonzero.

I tried to move the centerpoint step by step, and finally i succeeded with center.x = 252 and center.y = 640.
I don´t understand why, cause my windowsize is 125*125.
Must i set windowextension or what ?
0
 
LVL 15

Accepted Solution

by:
NickRepin earned 250 total points
ID: 1414543
I've tried to correct type error and made another one... :)

If you calculate the center point of the metafile correctly, the code in my answer will rotate metafile around it's center without any problem.

Suppose, you playing metafile in rect 20,30,100,150. And, as I understood, you want to rotate it around the center of this rectangle.
If so, the center you must use in code is 60,90 ( [100-20]/2+20, [150-30]/2+30 ). And not the center of the metafile itself
(the center of the metafile is width/2,height/2 - 40,60 in our case).

Next, if you want to resize metafile, say, twice, use SetViewportExtEx(2,2). Then metafile appears rotated around its center in rect 40,60,200,300. In this case the center of the resized metafile on screen will be in 120,180 and the metafile will seem shifted to right and down (and twice size, of course).

If you want to keep the center of the metafile on screen in first point, 60,90, then use SetViewportOrgEx(60-120,90-180).

I assume the size of window is 1,1 and its origin is 0,0.

If you have more question, feel free to write me directly to nick@rtzi.ru


By the way, the second CombineTransform is not necessary. It's enough to set x2.eDX=Pivot.x, x2.eDY=Pivot.y. Moreover, the rotation may be done in one step. But this is no so simple - it's need to apply some mathematics to fill XFORM.
0
 
LVL 15

Expert Comment

by:NickRepin
ID: 1414544
Another words, if I understood, instead of NeedleSize/2 use
Pivot=Origo
0

Featured Post

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this video, viewers will be given step by step instructions on adjusting mouse, pointer and cursor visibility in Microsoft Windows 10. The video seeks to educate those who are struggling with the new Windows 10 Graphical User Interface. Change Cu…

695 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question