티스토리 뷰
목차
반응형
C# 3D 프로그래밍, GDI+ Euler Rotation 표현
프로젝트 - WindowsApplication2.zip
C#에서 3D 구현을 위해 GDI+를 사용하기 위한 기본 구성은 다음과 같습니다.
- X, Y, Z의 값을 갖는 클래스를 한 개 생성해야 합니다.
- 3D 변환을 위한 공식에 대입될 값들을 조절할 줄 알아야 합니다.
- 시점을 설정할 카메라 클래스도 설정해야 합니다.
- X, Y, X에 몇 가지 공식을 대입해야 합니다.
직접 2D에서 3D로 변환할 방법은 구체적으론 없지만, 평면에서 이를 조절하는 방안과(Z축의 위치 계산 등) 24개로 이루어진 각 점(정면, 후면, 좌, 우, 상, 하 등 각 4점)의 위치 계산 및 고정을 위한 배열 활용이 중요합니다.
2D <-> 3D간 변환 공식은 아래 사이트를 참고하세요.
아래는 주요 소스입니다.
Cube 그리기 부분
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 public Bitmap drawCube(Point drawOrigin){//FRONT FACE//Top Left - 7//Top Right - 4//Bottom Left - 6//Bottom Right - 5//Vars//Will be actual 2D drawing pointsPointF[] point3D = new PointF[24];Point tmpOrigin = new Point(0, 0);//Used for referenceMath3D.Point3D point0 = new Math3D.Point3D(0, 0, 0);// Zoom factor is set with the monitor width to// keep the cube from being distorteddouble zoom = (double)Screen.PrimaryScreen.Bounds.Width / 1.5;//Set up the cubeMath3D.Point3D[] cubePoints = fillCubeVertices(width, height, depth);//Calculate the camera Z position to stay constant despite rotation//anchor pointMath3D.Point3D anchorPoint = (Math3D.Point3D)cubePoints[4];double cameraZ =-(((anchorPoint.X - cubeOrigin.X) * zoom)/ cubeOrigin.X) + anchorPoint.Z;camera1.Position = new Math3D.Point3D(cubeOrigin.X, cubeOrigin.Y, cameraZ);//Apply Rotations, moving the cube to a corner then back to middlecubePoints = Math3D.Translate(cubePoints, cubeOrigin, point0);cubePoints = Math3D.RotateX(cubePoints, xRotation); //The order of thesecubePoints = Math3D.RotateY(cubePoints, yRotation); //rotations is the sourcecubePoints = Math3D.RotateZ(cubePoints, zRotation); //of Gimbal LockcubePoints = Math3D.Translate(cubePoints, point0, cubeOrigin);//Convert 3D Points to 2DMath3D.Point3D vec;for (int i = 0; i < point3D.Length; i++){vec = cubePoints[i];if (vec.Z - camera1.Position.Z >= 0){point3D[i].X = (int)((double)-(vec.X - camera1.Position.X) /(-0.1f) * zoom) + drawOrigin.X;point3D[i].Y = (int)((double)(vec.Y - camera1.Position.Y) /(-0.1f) * zoom) + drawOrigin.Y;}else{tmpOrigin.X = (int)((double)(cubeOrigin.X - camera1.Position.X) /(double)(cubeOrigin.Z - camera1.Position.Z) * zoom) +drawOrigin.X;tmpOrigin.Y = (int)((double)-(cubeOrigin.Y - camera1.Position.Y) /(double)(cubeOrigin.Z - camera1.Position.Z) * zoom) +drawOrigin.Y;point3D[i].X = (float)((vec.X - camera1.Position.X) /(vec.Z - camera1.Position.Z) * zoom + drawOrigin.X);point3D[i].Y = (float)(-(vec.Y - camera1.Position.Y) /(vec.Z - camera1.Position.Z) * zoom + drawOrigin.Y);point3D[i].X = (int)point3D[i].X;point3D[i].Y = (int)point3D[i].Y;}}cs
좌표 변환 X
1234567891011121314151617181920212223 public static Point3D RotateX(Point3D point3D, double degrees){//Here we use Euler's matrix formula for// rotating a 3D point x degrees around the x-axis//[ a b c ] [ x ] [ x*a + y*b + z*c ]//[ d e f ] [ y ] = [ x*d + y*e + z*f ]//[ g h i ] [ z ] [ x*g + y*h + z*i ]//[ 1 00 ]//[ 0 cos(x) sin(x)]//[ 0 -sin(x) cos(x)]//Convert degrees to radian for .Net Cos/Sin functionsdouble cDegrees = (Math.PI * degrees) / 180.0f;double cosDegrees = Math.Cos(cDegrees);double sinDegrees = Math.Sin(cDegrees);double y = (point3D.Y * cosDegrees) + (point3D.Z * sinDegrees);double z = (point3D.Y * -sinDegrees) + (point3D.Z * cosDegrees);return new Point3D(point3D.X, y, z);}cs
C# 3D 프로그래밍, GDI+ Euler Rotation 표현
반응형