-
November 16th, 2020, 05:48 PM
#1
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
Last edited by Cambalinho; November 16th, 2020 at 05:52 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|