티스토리 뷰

목차

    반응형

    C# 3D 프로그래밍, GDI+ Euler Rotation 표현

     

    프로젝트 - WindowsApplication2.zip

     

    C Sharp - GDI+ Euler Rotation
    [C# 3D 프로그래밍] GDI 표현, Euler Rotation

     

    C#에서 3D 구현을 위해 GDI+를 사용하기 위한 기본 구성은 다음과 같습니다.

     

    - X, Y, Z의 값을 갖는 클래스를 한 개 생성해야 합니다.

    - 3D 변환을 위한 공식에 대입될 값들을 조절할 줄 알아야 합니다.

    - 시점을 설정할 카메라 클래스도 설정해야 합니다.

    - X, Y, X에 몇 가지 공식을 대입해야 합니다.

     

    직접 2D에서 3D로 변환할 방법은 구체적으론 없지만, 평면에서 이를 조절하는 방안과(Z축의 위치 계산 등) 24개로 이루어진 각 점(정면, 후면, 좌, 우, 상, 하 등 각 4점)의 위치 계산 및 고정을 위한 배열 활용이 중요합니다.

     

    2D <-> 3D간 변환 공식은 아래 사이트를 참고하세요.

    아래는 주요 소스입니다.

     

    Cube 그리기 부분

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    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 points
        PointF[] point3D = new PointF[24]; 
        Point tmpOrigin = new Point(00);
     
        //Used for reference
        Math3D.Point3D point0 = new Math3D.Point3D(000);
     
        // Zoom factor is set with the monitor width to 
        // keep the cube from being distorted
        double zoom = (double)Screen.PrimaryScreen.Bounds.Width / 1.5;
     
        //Set up the cube
        Math3D.Point3D[] cubePoints = fillCubeVertices(width, height, depth);
     
        //Calculate the camera Z position to stay constant despite rotation    
        //anchor point
        Math3D.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 middle
        cubePoints = Math3D.Translate(cubePoints, cubeOrigin, point0);
        cubePoints = Math3D.RotateX(cubePoints, xRotation); //The order of these
        cubePoints = Math3D.RotateY(cubePoints, yRotation); //rotations is the source
        cubePoints = Math3D.RotateZ(cubePoints, zRotation); //of Gimbal Lock
        cubePoints = Math3D.Translate(cubePoints, point0, cubeOrigin);
     
        //Convert 3D Points to 2D
        Math3D.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

     

    C# 3D 프로그래밍, GDI+ Euler Rotation 표현
    [C# 3D 프로그래밍] GDI 표현, Euler Rotation

     

    좌표 변환 X

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    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 functions
        double 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 표현

    반응형