Home > Articles

  • Print
  • + Share This
This chapter is from the book

This chapter is from the book

Exploring the Program Listings

Listings 3.25 and 3.26 show the complete code for the CGraphics2DView class, including the Graphics2DView.h header file and the Graphics2DView.cpp implementation file. Many other files were created by AppWizard when you started the Graphics2D application project. Because you didn't modify those files, they aren't shown here. However, you can easily view any of the project's files by loading them with Visual C++'s editor (or any other text editor).

Listing 3.25 The CGraphics2DView Class's Header File

// Graphics2DView.h : interface of the CGraphics2DView class
//


#pragma once

typedef double MATRIX3X3[3][3];

typedef struct vector
{
  int x, y, w;
} VECTOR;

typedef struct shape
{
  int numVerts;
  VECTOR* vertices;
} SHAPE;

class CGraphics2DView : public CView
{
protected: // create from serialization only
  CGraphics2DView();
  DECLARE_DYNCREATE(CGraphics2DView)

// Attributes
public:
  CGraphics2DDoc* GetDocument() const;
protected:
  SHAPE m_polygon;
  VECTOR m_vectors[4];
  int m_rotate;
  double m_xScale, m_yScale;
  double m_xTranslate, m_yTranslate;

// Operations
public:

// Overrides
  public:
  virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:

// Implementation
public:
  virtual ~CGraphics2DView();
#ifdef _DEBUG
  virtual void AssertValid() const;
  virtual void Dump(CDumpContext& dc) const;
#endif

protected:
  void DrawShape(CDC* pDC, SHAPE& shape1);
  void Translate(MATRIX3X3& m, int xTrans, int yTrans);
  void Scale(MATRIX3X3& m, double xScale, double yScale);
  void Rotate(MATRIX3X3& m, int degrees);
  void Transform(SHAPE& shape, MATRIX3X3& m);
  void MultMatrix(MATRIX3X3& product,
    MATRIX3X3& matrix1, MATRIX3X3& matrix2);
  void InitMatrix(MATRIX3X3& m);
  void CopyMatrix(MATRIX3X3& dst, MATRIX3X3& src);

// Generated message map functions
protected:
  DECLARE_MESSAGE_MAP()
public:
  afx_msg void OnTransformRotate();
  afx_msg void OnTransformScale();
  afx_msg void OnTransformTranslate();
  afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
};

#ifndef _DEBUG // debug version in Graphics2DView.cpp
inline CGraphics2DDoc* CGraphics2DView::GetDocument() const
  { return reinterpret_cast<CGraphics2DDoc*>(m_pDocument); }
#endif

Listing 3.26 The CGraphics2DView Class's Implementation File

// Graphics2DView.cpp : implementation of the CGraphics2DView class
//

#include "stdafx.h"
#include "Graphics2D.h"

#include "Graphics2DDoc.h"
#include "Graphics2DView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include <math.h>
#include "TransformDlg.h"

// CGraphics2DView

IMPLEMENT_DYNCREATE(CGraphics2DView, CView)

BEGIN_MESSAGE_MAP(CGraphics2DView, CView)
  ON_COMMAND(ID_TRANSFORM_ROTATE, OnTransformRotate)
  ON_COMMAND(ID_TRANSFORM_SCALE, OnTransformScale)
  ON_COMMAND(ID_TRANSFORM_TRANSLATE, OnTransformTranslate)
  ON_WM_RBUTTONDOWN()
END_MESSAGE_MAP()

// CGraphics2DView construction/destruction

CGraphics2DView::CGraphics2DView()
{
  // TODO: add construction code here
  m_polygon.numVerts = 4;
  m_polygon.vertices = m_vectors;
  m_vectors[0].x = 0;
  m_vectors[0].y = 0;
  m_vectors[0].w = 1;
  m_vectors[1].x = 100;
  m_vectors[1].y = 0;
  m_vectors[1].w = 1;
  m_vectors[2].x = 100;
  m_vectors[2].y = 50;
  m_vectors[2].w = 1;
  m_vectors[3].x = 0;
  m_vectors[3].y = 75;
  m_vectors[3].w = 1;

  m_rotate = 0;
  m_xScale = 1;
  m_yScale = 1;
  m_xTranslate = 0;
  m_yTranslate = 0;
}

CGraphics2DView::~CGraphics2DView()
{
}

BOOL CGraphics2DView::PreCreateWindow(CREATESTRUCT& cs)
{
  // TODO: Modify the Window class or styles here by modifying
  // the CREATESTRUCT cs

  return CView::PreCreateWindow(cs);
}

// CGraphics2DView drawing

void CGraphics2DView::OnDraw(CDC* pDC)
{
  CGraphics2DDoc* pDoc = GetDocument();
  ASSERT_VALID(pDoc);

  // TODO: add draw code for native data here
  DrawShape(pDC, m_polygon);
}


// CGraphics2DView diagnostics

#ifdef _DEBUG
void CGraphics2DView::AssertValid() const
{
  CView::AssertValid();
}

void CGraphics2DView::Dump(CDumpContext& dc) const
{
  CView::Dump(dc);
}

CGraphics2DDoc* CGraphics2DView::GetDocument() const
{
  ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGraphics2DDoc)));
  return (CGraphics2DDoc*)m_pDocument;
}
#endif //_DEBUG


// CGraphics2DView message handlers

void CGraphics2DView::OnTransformRotate()
{
  // TODO: Add your command handler code here
  CTransformDlg dlg;
  dlg.m_xAxis = 0;
  dlg.m_yAxis = 0;

  INT_PTR response = dlg.DoModal();

  if (response == IDOK)
    m_rotate = (int) dlg.m_xAxis;
}

void CGraphics2DView::OnTransformScale()
{
  // TODO: Add your command handler code here
  CTransformDlg dlg;
  dlg.m_xAxis = 1;
  dlg.m_yAxis = 1;

  INT_PTR response = dlg.DoModal();

  if (response == IDOK)
  {
    m_xScale = dlg.m_xAxis;
    m_yScale = dlg.m_yAxis;
  }
}

void CGraphics2DView::OnTransformTranslate()
{
  // TODO: Add your command handler code here
  CTransformDlg dlg;
  dlg.m_xAxis = 0;
  dlg.m_yAxis = 0;

  INT_PTR response = dlg.DoModal();

  if (response == IDOK)
  {
    m_xTranslate = dlg.m_xAxis;
    m_yTranslate = dlg.m_yAxis;
  }
}

void CGraphics2DView::OnRButtonDown(UINT nFlags, CPoint point)
{
  // TODO: Add your message handler code here and/or call default
  MATRIX3X3 m;
  InitMatrix(m);

  Translate(m, (int) m_xTranslate, (int) m_yTranslate);
  Scale(m, m_xScale, m_yScale);
  Rotate(m, m_rotate);
  Transform(m_polygon, m);

  m_rotate = 0;
  m_xScale = 1;
  m_yScale = 1;
  m_xTranslate = 0;
  m_yTranslate = 0;

  Invalidate(TRUE);

  CView::OnRButtonDown(nFlags, point);
}

void CGraphics2DView::InitMatrix(MATRIX3X3& m)
{
  m[0][0]=1; m[0][1]=0; m[0][2]=0;
  m[1][0]=0; m[1][1]=1; m[1][2]=0;
  m[2][0]=0; m[2][1]=0; m[2][2]=1;
}

void CGraphics2DView::CopyMatrix(MATRIX3X3& dst, MATRIX3X3& src)
{
  for (int i=0; i<3; ++i)
   for (int j=0; j<3; ++j)
     dst[i][j] = src[i][j];
}

void CGraphics2DView::MultMatrix(MATRIX3X3& product,
   MATRIX3X3& matrix1, MATRIX3X3& matrix2)
{
  for (int x=0; x<3; ++x)
    for (int y=0; y<3; ++y)
    {
      double sum = 0;
      for (int z=0; z<3; ++z)
        sum += matrix1[x][z] * matrix2[z][y];
      product[x][y] = sum;
    }
}

void CGraphics2DView::Translate(MATRIX3X3& m, int xTrans, int yTrans)
{
  MATRIX3X3 m1, m2;

  m1[0][0]=1;    m1[0][1]=0;    m1[0][2]=0;
  m1[1][0]=0;    m1[1][1]=1;    m1[1][2]=0;
  m1[2][0]=xTrans; m1[2][1]=yTrans; m1[2][2]=1;

  MultMatrix(m2, m1, m);
  CopyMatrix(m, m2);
}

void CGraphics2DView::Scale(MATRIX3X3& m, double xScale, double yScale)
{
  MATRIX3X3 m1, m2;

  m1[0][0]=xScale; m1[0][1]=0;   m1[0][2]=0;
  m1[1][0]=0;   m1[1][1]=yScale; m1[1][2]=0;
  m1[2][0]=0;   m1[2][1]=0;   m1[2][2]=1;

  MultMatrix(m2, m1, m);
  CopyMatrix(m, m2);
}

void CGraphics2DView::Rotate(MATRIX3X3& m, int degrees)
{
  MATRIX3X3 m1, m2;

  if (degrees == 0) return;

  double radians = 6.283185308 / (360.0 / degrees);
  double c = cos(radians);
  double s = sin(radians);

  m1[0][0]=c; m1[0][1]=s; m1[0][2]=0;
  m1[1][0]=-s; m1[1][1]=c; m1[1][2]=0;
  m1[2][0]=0; m1[2][1]=0; m1[2][2]=1;
  
  MultMatrix(m2, m1, m);
  CopyMatrix(m, m2);
}

void CGraphics2DView::Transform(SHAPE& shape, MATRIX3X3& m)
{
  int transformedX, transformedY;

  for (int x=0; x<shape.numVerts; ++x)
  {
    transformedX = (int) (shape.vertices[x].x * m[0][0] +
      shape.vertices[x].y * m[1][0] + m[2][0]);
    transformedY = (int) (shape.vertices[x].x * m[0][1] +
      shape.vertices[x].y * m[1][1] + m[2][1]);
    shape.vertices[x].x = transformedX;
    shape.vertices[x].y = transformedY;
  }
}

void CGraphics2DView::DrawShape(CDC* pDC, SHAPE& shape1)
{
  int newX, newY, startX, startY;
  RECT clientRect;

  GetClientRect(&clientRect);
  int maxY = clientRect.bottom;

  for (int x=0; x<shape1.numVerts; ++x)
  {
    newX = shape1.vertices[x].x;
    newY = maxY - shape1.vertices[x].y;
    if (x == 0)
    {
      pDC->MoveTo(newX, newY);
      startX = newX;
      startY = newY;
    }
    else
      pDC->LineTo(newX, newY);
  }

  pDC->LineTo(startX, startY);
}
  • + Share This
  • 🔖 Save To Your Account