Graphics base (b) pattern converter: 3D parallel projection

Because I did not understand too much, so this would just write some more. So much classification, looking at a headache.

 

Ready (homogeneous coordinates / Graphics )

BaseClass new class (.h .cpp), add the necessary parameters and functions.

typedef double array2d[5][5];
typedef double array[24];

class CBaseClass
{
public:int theta_y, phi_x, xx, yy, nn, n;
    array X, Y, Z, C, XT, YT, ZT, XP, YP, ZP, CP;
    array2d A, Ah, Aw;
    double ax[9], ay[9], az[9];
    double bx[9], by[9], bz[9];
public:
    CBaseClass();
    virtual ~CBaseClass();
    void ReadWorkpiece();void Calculate(array2d B);
    void MCalculate(array2d B);
    void XCalculate(array2d B);
    void Drawtext();
    void Display();
    void Draw();
    void Drawve();
    void Drawvt();
    void Drawse();
    void Drawst();
    void DrawViewV(CDC* pdc, CRect rr);
    void DrawViewH(CDC* pdc, CRect rr);
    void DrawViewW(CDC* pdc, CRect rr);

    void moveto(double x, double y, CDC* pdc);
    void lineto(double x, double y, CDC* pdc);
    void cleanMatrice(array2d B);
};

(Some of the basic functions to one before, not repeat them here. Other auxiliary functions when used to say.)

 

1, the homogeneous coordinates

 Line generation, then the high school level is enough. Use homogeneous coordinates, it is to allow panning operation and can rotate, zoom and other operations processed together. Basic transformation will not repeat them here.

 

2, graphics

 

void CBaseClass::ReadWorkpiece()
{
    X[1] = 0; Y[1] = 0; Z[1] = 0; C[1] = 1;
    X[2] = 45; Y[2] = 0; Z[2] = 0; C[2] = 1;
    X[3] = 45; Y[3] = 37; Z[3] = 0; C[3] = 1;
    X[4] = 0; Y[4] = 37; Z[4] = 0; C[4] = 1;
    X[5] = 0; Y[5] = 37; Z[5] = 45; C[5] = 1;
    X[6] = 0; Y[6] = 0; Z[6] = 45; C[6] = 1;
    X[7] = 12; Y[7] = 0; Z[7] = 45; C[7] = 1;
    X[8] = 30; Y[8] = 0; Z[8] = 14; C[8] = 1;
    X[9] = 45; Y[9] = 0; Z[9] = 14; C[9] = 1;
    X[10] = 45; Y[10] = 37; Z[10] = 14; C[10] = 1;
    X[11] = 30; Y[11] = 37; Z[11] = 14; C[11] = 1;
    X[12] = 12; Y[12] = 37; Z[12] = 45; C[12] = 1;
}

 

Three View

(Where the projection plane and a front view of xoz surface.)

 Graphics perspective (isometric ramp) and disassembling step of FIG:

 

 

 Direct a vertical front view projection; the vertical projection plan view, rotated by 90 ° about the x axis; rear side view of the vertical projection, rotation about the z axis 90 °.

Code below, has a top and a side view of FIG calculate the rotation matrix.

void CGeoTrans3DView::OnV()
{
    // the TODO: this addition command handler code
     // m_str = "front view XOZ"; 
    CBaseClass My;
    my.cleanMatrice(my.A);
    my.A[1][1] = 1;
    my.A[3][3] = 1;
    my.A[4][4] = 1;
    my.Display();
}

void CGeoTrans3DView::OnH()
{
    // the TODO: this addition command handler code
     // m_str = "top view XOY"; 
    CBaseClass My;
    my.cleanMatrice(my.Ah);
    my.Ah[1][1] = 1;
    my.Ah[2][3] = -1;
    my.Ah[4][4] = 1;
    my.Display();
}

void CGeoTrans3DView::OnW()
{
    // the TODO: this addition command handler code
     // m_str = "side YOZ"; 
    CBaseClass My;
    my.cleanMatrice(my.Aw);
    my.Aw [ 2 ] [ 1 ] = - 1 ;
    my.Aw [ 3 ] [ 3 ] = 1 ;
    my.Aw [ 4 ] [ 4 ] = 1 ;
    my.Display();
}

 Auxiliary function  Display () , DrawViewV (CDC * the PDC, CRect rr) :

void CBaseClass::Display()
{
    CFrameWnd* pWnd = (CFrameWnd*)AfxGetApp()->m_pMainWnd;
    CDC* pdc = pWnd->GetActiveView()->GetDC();
    CRect rr;
    ::GetClientRect(pWnd->GetActiveView()->m_hWnd, rr);

    DrawViewV(pdc, rr);
    pWnd->GetActiveView()->ReleaseDC(pdc);
}

void CBaseClass::DrawViewV(CDC * pdc, CRect rr)
{
    xx = rr.right / 2;
    yy = rr.bottom / 2;
    Calculate(A);
    moveto(xx + XT[1], yy - ZT[1], pdc);
    for (int I = 2; I <= 12; ++I)
        lineto(xx + XT[I], yy - ZT[I], pdc);
    moveto(xx + XT[1], yy - ZT[1], pdc);
    lineto(xx + XT[4], yy - ZT[4], pdc);
    moveto(xx + XT[1], yy - ZT[1], pdc);
    lineto(xx + XT[6], yy - ZT[6], pdc);
    moveto(xx + XT[7], yy - ZT[7], pdc);
    lineto(xx + XT[12], yy - ZT[12], pdc);
    moveto(xx + XT[3], yy - ZT[3], pdc);
    lineto(xx + XT[10], yy - ZT[10], pdc);
    moveto(xx + XT[2], yy - ZT[2], pdc);
    lineto(xx + XT[9], yy - ZT[9], pdc);
    moveto(xx + XT[12], yy - ZT[12], pdc);
    lineto(xx + XT[5], yy - ZT[5], pdc);
    moveto(xx + XT[8], yy - ZT[8], pdc);
    lineto(xx + XT[11], yy - ZT[11], pdc);
}

 

Axonometric projection (axonometric / trimetric)

Axonometric abandoned measurable, but adds a certain realism (realistic perspective of the strongest, but I did not get to know ...). Its principle is to allow us to see as much of the surface of an object. Graphics we encountered in solid geometry title, the second test is generally oblique projection come, so I will only draw oblique second test ...

Isometric view, an angle between the X, Y, Z three-axis is 120 °, the axial stretching coefficient is 1 and the three axes.

Two oblique isometric view, an angle between the X, Y-axis is 135 °, the angle between the X, Z axis is 90 °, the angle between the Y, Z-axis is 135 °, and the axial stretching of the Y-axis of 0.5, X, Z-axis axial stretching ratio of 1.

1, is isometric

 Isometric measurements and positive difference in principle is Tv, i.e., an isometric view, in vertical projection can be rotated; n after rotation of the second test, a need to adjust the observation position in the axial direction. . . I say? Tap spray orz.

 Similarly, three measurements can be pushed positive.

void CGeoTrans3DView::OnVe()
{
    // the TODO: this addition command handler code
     // m_str = "n FIG other side"; 
    CBaseClass My;
    my.theta_y = 45 ; // the Y-axis angle 
    my.phi_x = 125 ; // X-axis angle 
    my.cleanMatrice (my.A);
    my.A[1][1] = (float)cos(my.theta_y*PI / 180);
    my.A[1][2] = (float)sin(my.theta_y*PI / 180)*(float)sin(my.phi_x*PI / 180);
    my.A[2][2] = (float)cos(my.phi_x*PI / 180);
    my.A[3][1] = (float)sin(my.theta_y*PI / 180);
    my.A[3][2] = (float)-cos(my.theta_y*PI / 180)*(float)sin(my.phi_x*PI / 180);
    my.A[4][4] = 1;
    my.Drawve();
}


void CGeoTrans3DView::OnVt()
{
    // the TODO: this addition command handler code
     // m_str = "positive sides of FIG."; 
    CBaseClass My;
    my.theta_y = 115 ; // the Y-axis angle 
    my.phi_x = 25 ; // X-axis angle 
    my.cleanMatrice (my.A);
    my.A[1][1] = (float)cos(my.theta_y*PI / 180);
    my.A[1][2] = (float)sin(my.theta_y*PI / 180)*(float)sin(my.phi_x*PI / 180);
    my.A[2][2] = (float)cos(my.phi_x*PI / 180);
    my.A[3][1] = (float)sin(my.theta_y*PI / 180);
    my.A[3][2] = (float)-cos(my.theta_y*PI / 180)*(float)sin(my.phi_x*PI / 180);
    my.A[4][4] = 1;
    my.Drawvt();
}

 Helper  Drawve () ( Drawvt () the same, but changed positions) :

void CBaseClass::Drawve()
{
    int I;
    CFrameWnd* pWnd = (CFrameWnd*)AfxGetApp()->m_pMainWnd;
    CDC* pdc = pWnd->GetActiveView()->GetDC();
    CRect rr;
    ::GetClientRect(pWnd->GetActiveView()->m_hWnd, rr);
    xx = rr.right / 3;
    yy = rr.bottom * 2 / 3;
    MCalculate(A);
    Drawtext();
    moveto(xx + XT[1], yy - YT[1], pdc);
    for (I = 2; I <= 12; ++I)
        lineto(xx + XT[I], yy - YT[I], pdc);
    moveto(xx + XT[1], yy - YT[1], pdc);
    lineto(xx + XT[4], yy - YT[4], pdc);
    moveto(xx + XT[1], yy - YT[1], pdc);
    lineto(xx + XT[6], yy - YT[6], pdc);
    moveto(xx + XT[7], yy - YT[7], pdc);
    lineto(xx + XT[12], yy - YT[12], pdc);
    moveto(xx + XT[3], yy - YT[3], pdc);
    lineto(xx + XT[10], yy - YT[10], pdc);
    moveto(xx + XT[2], yy - YT[2], pdc);
    lineto(xx + XT[9], yy - YT[9], pdc);
    moveto(xx + XT[12], yy - YT[12], pdc);
    lineto(xx + XT[5], yy - YT[5], pdc);
    moveto(xx + XT[8], yy - YT[8], pdc);
    lineto(xx + XT[11], yy - YT[11], pdc);
    pWnd->GetActiveView()->ReleaseDC(pdc);
}

 

2, oblique isometric

(Projection direction not perpendicular to the plane of projection.)

 Conversion to the matrix, i.e. shearing.

void CGeoTrans3DView :: ounces ()
{
    // the TODO: this addition command handler code
     // m_str = "other oblique side of FIG."; 
    CBaseClass My;
    my.cleanMatrice(my.A);
    my.A[1][1] = 1;
    my.A[2][2] = 1;    
    my.A [ . 3 ] [ . 1 ] = 0.707f ; // X-direction shearing 
    my.A [ . 3 ] [ 2 ] = 0.707f ; // the Y direction shearing 
    my.A [ . 4 ] [ . 4 ] = . 1 ;
    my.Drawse();
}

void CGeoTrans3DView :: connect ()
{
    // the TODO: this addition command handler code
     // m_str = "oblique sides of FIG."; 
    CBaseClass My;
    my.cleanMatrice(my.A);
    my.A[1][1] = 1;
    my.A[2][2] = 1;
    my.A [ . 3 ] [ . 1 ] = 0.3535f ; // X-direction shearing 
    my.A [ . 3 ] [ 2 ] = 0.3535f ; // the Y direction shearing 
    my.A [ . 4 ] [ . 4 ] = . 1 ;
    my.Drawst ();
}

Auxiliary functions: Drawse (), Drawst () and Drawve () the same, but changed positions

 

Guess you like

Origin www.cnblogs.com/CowryGao/p/12638469.html