SetWorldTransform my rotation is also scaling and I do not want it to do that.

Jon 21 Reputation points
2021-12-02T19:53:15.64+00:00

I have the same result from 2 attempts.

  1. SetViewportOrgEx to the upper left corner, followed by SetWorldTransform
    where my matrix is
    xForm.eM11 = cos_ang;
    xForm.eM12 = sin_ang;
    xForm.eM21 = -sin_ang;
    xForm.eM22 = xForm.eM11;
    xForm.eDx = (theCenterPt.x - (cos_ang * theCenterPt.x)) + ((sin_ang * theCenterPt.y));
    xForm.eDy = (theCenterPt.y - (sin_ang * theCenterPt.x)) - ((cos_ang * theCenterPt.y));

and
2)
where SetViewportOrgEx is the center and eDx, eDy are 0,0

it rotates perfectly around the point that I want (the center point mentioned in the code) but as it rotates it shrinks as if using the cos values as scale factors, so at 90 degrees its a pixel or gone, I can't tell and at 0 degrees its normal.

I have been trying to understand what triggers it to do a scale instead of a rotation, or what I am doing wrong, but nothing is really clicking for me. I just want it to rotate, nothing else. The above is from an example that is supposed to do exactly that. Other examples do not work at all, or do the same thing, or rotate around the wrong point.

Any help is very much appreciated, even if its pointing to a document I missed. Ive been trying to run down a doc that explains how it decides that the numbers mean scale instead of move or rotate, with no real luck. Thank you.

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,427 questions
0 comments No comments
{count} votes

Accepted answer
  1. Xiaopo Yang - MSFT 11,496 Reputation points Microsoft Vendor
    2021-12-03T05:57:29.707+00:00

    I have tested SetViewportOrgEx SetWorldTransform which work perfectly. Could you please show a minimal, reproducible sample without private information?

    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: Add any drawing code that uses hdc here...
    
            //SetRect(&rc, 0, 0, 100, 100);
            GetClientRect(hWnd,&rc);
    
            SetViewportOrgEx(hdc, rc.right / 2, rc.bottom / 2, NULL);
            if (RectVisible(hdc, &rc))
            {
                //Polyline(hdc, aptRectangle, 5);
                Ellipse(hdc, ( - 100), ( + 50),( + 100), ( - 50));
                SetGraphicsMode(hdc, GM_ADVANCED);
                XFORM xForm;
                xForm.eM11 = (FLOAT)0.8660;
                xForm.eM12 = (FLOAT)0.5000;
                xForm.eM21 = (FLOAT)-0.5000;
                xForm.eM22 = (FLOAT)0.8660;
                xForm.eDx = (FLOAT)0.0;
                xForm.eDy = (FLOAT)0.0;
                SetWorldTransform(hdc, &xForm);
                Ellipse(hdc, (-100), (+50), (+100), (-50));
            }
    
            EndPaint(hWnd, &ps);
        }
        break;
    
    0 comments No comments

6 additional answers

Sort by: Most helpful
  1. Jon 21 Reputation points
    2021-12-03T12:42:37.837+00:00

    I will try today.

    0 comments No comments

  2. Jon 21 Reputation points
    2021-12-03T14:18:03.43+00:00

    Ok, that exercise shows that its happening somewhere else in my code base, not at the rotation.
    A basic windowed c++ project, modifying the case as you did, with virtually the same code I have been fighting with, works fine, no scaling, and everything does what I expected it to do. I am going to call this answered for now since the problem is elsewhere. Warning: if you are sensitive to motion sickness or prone to seizures you may not want to run this one.

    case WM_PAINT:
            {
                static double ang{};
                const double cang{cos(ang)}, sang{sin(ang)};
                ang += 0.175;
                ang = fmod(ang, 6.28);
                PAINTSTRUCT ps;            
                HDC hdc = BeginPaint(hWnd, &ps); 
                //Rectangle(hdc, 100, 100, 200, 200);
                XFORM xForm;
                SetGraphicsMode(hdc, GM_ADVANCED);
    
                SetViewportOrgEx(hdc,
                  (150 - (cang * 150)) + ((sang * 150)),
                  (150 - (sang * 150)) - ((cang * 150)), nullptr);
    
                xForm.eM11 = cang; 
                xForm.eM12 = sang;
                xForm.eM21 = -sang;
                xForm.eM22 = cang;
                xForm.eDx = 0;// (theCenterPt.x - (cos_ang * theCenterPt.x)) + ((sin_ang * theCenterPt.y));
                xForm.eDy = 0;
                SetWorldTransform(hdc, &xForm);
    
                Rectangle(hdc, 100, 100, 200, 200);
    
                EndPaint(hWnd, &ps);    
                InvalidateRect(hWnd,0, 0);
            }
            break;
    
    0 comments No comments