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,352 questions
0 comments No comments
{count} votes

Accepted answer
  1. Xiaopo Yang - MSFT 10,706 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. Castorix31 80,896 Reputation points
    2021-12-02T20:27:05.303+00:00

    If I test the MSDN function TransformAndDraw with ROTATE from Using Coordinate Spaces and Transformations
    by drawing twice in black, then in red , it rotates correctly :

    154633-rotate.jpg

    2 people found this answer helpful.
    0 comments No comments

  2. Jon 21 Reputation points
    2021-12-02T20:37:25.967+00:00

    Yes, that is one of the examples I am following. And at 85 degrees, it scales the rotated image to nothing.
    2) is basically a copy of that code, apart from moving the origin and not having the cases that I do not need.
    Do you have something that explains why it is trying to scale it or how to fix that issue? Mine works at small angles too, or close enough... which notably have the trig component close to 1

    EDIT changing the cos components to 1 prevents scales, but then it rotates about another point (or different points?) which I am not sure how to move back to my center. That would work too, if you can explain THAT matrix setup.


  3. Jon 21 Reputation points
    2021-12-03T00:00:13.31+00:00

    setting 11 and 22 both to 1 and it stops scaling but the rotation point is wrong. The scaling component and the 2 cosine components share the same variables, and it keeps scaling it to the cosine so setting those to 1 stops that. For angles 0-30 sure, it rotates and is 'sorta unscaled'. For 40+ it shrinks at an increasing rate to 90 and so on.

    1 for 11 and 0 for 12 shears it and moves it around. that gives 1,0, -sin, cos for 11, 12,21,22 and it no longer rotates (I want it to rotate....!)
    so we went from rotating and shrinking to shearing and moving.

    I will say it again, for case 2) in my original question, I have
    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);

    except 11,12,21,22 are from a user provided angle and I took the sin & cos of it to fill them in. Its the exact same thing as the example. But at 85 degrees, you can't even see the rotated object, it has been scaled so small. At 60 degrees its 1/2 size. And so on. It exactly matches the example, except for a leading move origin command.


  4. Jon 21 Reputation points
    2021-12-03T02:51:02.787+00:00

    Ok. Something is different, clearly, but I don't see it. Its a copy of the program you are using nearly... I guess I will have to just keep trial and error if there is no explains available for what turns on scaling.

    0 comments No comments