CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    Apr 2009
    Posts
    1,327

    how rotate a 2D image using 3D rotation?

    heres the functions that i use for rotation 3D:
    Code:
    //RotateImage.h:
    #include <iostream>
    #include <windows.h>
    #include <math.h>
    
    
    struct PointAPI
    {
        double X;
        double Y;
    };
    
    
    struct Position3D
    {
        double X;
        double Y;
        double Z;
    };
    
    
    struct Angle3D
    {
        double X;
        double Y;
        double Z;
        Position3D RotationPosition3D;
    };
    
    
    struct Size3D
    {
        double Width;
        double Height;
        double ZDepth;
        double distance;
    };
    
    
    const double Pi = 3.14159265358979;
    
    
     Angle3D ConvertDegreesToRadians(Angle3D rotation)
    {
        double deg2Rad;
        deg2Rad = Pi / 180;
        Angle3D DegreesToRadians;
        DegreesToRadians.X = rotation.X * deg2Rad;
        DegreesToRadians.Y = rotation.Y * deg2Rad;
        DegreesToRadians.Z = rotation.Z * deg2Rad;
        return DegreesToRadians;
    }
    
    
    Position3D Rotate(Position3D Position, Angle3D rotation)
    {
        Position3D ConvertedPosition;
        Angle3D RotationInRads;
        Position3D T;
    
    
        //Convert Degrees to Radians.. the PC uses Radians:
        RotationInRads = ConvertDegreesToRadians(rotation);
    
    
        //Convert the position to Zero for rotate on zero position...
        //using these way, the shape is rotated by it's center or what position we use:
        ConvertedPosition = Position;
        ConvertedPosition.X = Position.X - rotation.RotationPosition3D.X;
        ConvertedPosition.Y = Position.Y - rotation.RotationPosition3D.Y; //reversed because Y increments down
        ConvertedPosition.Z = Position.Z - rotation.RotationPosition3D.Z;
    
    
        //For 3D we must calculate the Z, X, Y rotation order:
    
    
        //Z axis  (Roll):
        T = ConvertedPosition;
            ConvertedPosition.X = T.X * cos(RotationInRads.Z) - T.Y * sin(RotationInRads.Z);
            ConvertedPosition.Y = T.X * sin(RotationInRads.Z) + T.Y * cos(RotationInRads.Z);
    
    
        //X axis  (Pitch):
        T = ConvertedPosition;
            ConvertedPosition.Y = T.Y * cos(RotationInRads.X) - T.Z * sin(RotationInRads.X);
            ConvertedPosition.Z = T.Y * sin(RotationInRads.X) + T.Z * cos(RotationInRads.X);
    
    
        //Y axis  (Yaw):
        T = ConvertedPosition;
            ConvertedPosition.X = T.Z * sin(RotationInRads.Y) + T.X * cos(RotationInRads.Y);
            ConvertedPosition.Z = T.Z * cos(RotationInRads.Y) - T.X * sin(RotationInRads.Y);
    
    
        //Go back to the new position:
        ConvertedPosition.X = ConvertedPosition.X + rotation.RotationPosition3D.X;
        ConvertedPosition.Y = ConvertedPosition.Y + rotation.RotationPosition3D.Y;
        ConvertedPosition.Z = ConvertedPosition.Z + rotation.RotationPosition3D.Z;
    
    
        return ConvertedPosition;
    }
    
    
    
    
    PointAPI ConvertPositon3DTo2D(Position3D Position, double CamDistance=100, PointAPI Center={0,0})
    {
        PointAPI ConvertedPosition;
        long PosZZDepth;
    
    
    
    
        //sum Z position with cam world distance:
        PosZZDepth = Position.Z + CamDistance;
        if (PosZZDepth == 0)
        {
            PosZZDepth = 1; //avoiding division by zero
        }
    
    
    
    
    
    
        //avoid drawing on back of the camera:
        if (PosZZDepth <= CamDistance)
        {
             PosZZDepth = 1;
             //World3DSize.distance = 1
        }
    
    
        //convert 3D(X, Y, Z) to 2D(X,Y):
        //ConvertedX = (ActualX * CamDistance /(CamDistance + ZPosition)) + HalfCenterOfWidth
        //ConvertedY = (ActualY * CamDistance /(CamDistance + ZPosition)) + HalfCenterOfHeight
        //for we draw the pixel on center, we must add half of the size:
        ConvertedPosition.X = (Position.X * CamDistance / PosZZDepth)+ Center.X;
        ConvertedPosition.Y = (Position.Y * CamDistance / PosZZDepth)+ Center.Y;
    
    
        return ConvertedPosition;
    }
    
    
    //Rotate an image:
    void RotationImage( HDC HDCDestination, HDC HDCSource , double AngleX, double AngleY, double AngleZ, double ImageWidth , double ImageHeight)
    {
    
    
        double PosX=0; double PosY=0;
    
    
        COLORREF tmpColor;
        Position3D pos;
        Angle3D ang;
    
    
        Size3D worldsize;
    
    
        ang.X = AngleX;
        ang.Y = AngleY;
        ang.Z = AngleZ;
        ang.RotationPosition3D.X = ImageWidth / 2;
        ang.RotationPosition3D.Y = ImageHeight / 2;
        ang.RotationPosition3D.Z = 500;
        worldsize.distance = 100;
        worldsize.Height = ImageHeight;
        worldsize.Width = ImageWidth;
        worldsize.ZDepth = 10;
        PointAPI apipos;
        //run a loop through the picture to change every pixel
        for (PosX = 0; PosX<ImageWidth; PosX++)
        {
            for (PosY = 0; PosY< ImageHeight; PosY++)
            {
                pos.X = PosX;
                pos.Y = PosY;
                //Get the color (using GetPixel):
                tmpColor = GetPixel(HDCSource, pos.X, pos.Y);
                if (tmpColor == CLR_INVALID) break;
                pos = Rotate(pos, ang);
                PointAPI rotpos{200.0,200.0};
                apipos = ConvertPositon3DTo2D(pos,100,rotpos);
                //Now set that data using the SetPixelV command
                if (SetPixelV(HDCDestination, apipos.X, apipos.Y, tmpColor) == CLR_INVALID) break;
    
    
            }
        }
    }
    and how i use the function:
    Code:
    #include "RotateImage.h"
    
    
    using namespace std;
    
    
    HDC  Image;
    HBITMAP HImage;
    int main()
    {
        Image=GetWindowDC(GetConsoleWindow() );
        HImage=(HBITMAP)(HBITMAP)LoadImage(NULL, "C:\\new\\bkgBox.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
        if(HImage==NULL)
            cout << GetLastError();
        HDC hdcSource = CreateCompatibleDC(GetDC(0));
        SelectObject(hdcSource, HImage);
        RotationImage(Image,hdcSource,300,0,0,256,256);
    
    
    
    
        //BitBlt(Image, 0, 0, 500, 500, hdcSource, 0, 0, SRCCOPY);
        cin.get();
        return  0;
    }
    why the X rotation is wrong? i use 300 degrees
    Name:  imagem_2020-11-16_224748.png
Views: 1307
Size:  1.5 KB
    Last edited by Cambalinho; November 16th, 2020 at 05:52 PM.

  2. #2
    Join Date
    Apr 2009
    Posts
    1,327

    Re: how rotate a 2D image using 3D rotation?

    i use these functions for rotate a pixel...
    1 - we get the pixel(the Z is zero) on RotationImage() and GetPixel();
    2 - all angles(X, Y and Z) must be converted in Radians(the computer use Radians and not Degrees) using ConvertDegreesToRadians();
    3 - the pixels must go to zero position(these is the 1st step for we rotate a pixel on a point(in these case is the center of image))... minus the rotation position on Rotate();
    4 - the pixel is rotated using the 3D Math rotation on Rotate();
    5 - we add the rotation position(2nd step) on Rotate();
    6 - we convert the 3D position to 2D position() using ConvertPositon3DTo2D().
    is my question\problem more explain? or needs more information?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured