12,996,728 members (78,622 online)
Tip/Trick
alternative version

#### Stats

8.4K views
11 bookmarked
Posted 29 May 2012

# 3D Vector Graphics Class

, 29 May 2012
 Rate this:
3D Vector Graphics class.

## Introduction

While displaying 3D objects on 2D, we have to convert the 3D Coordinates to corresponding 2D coordinates. Let us call it as projections. To create projections we have to do some sort of Vector Algebra.

## Background

Basically there are many types of projections; here we are referring only two types of projections

1. Orthographic Projections
2. In Orthographic projections, Projection P (x’, y’) on the 3D Point A(x, y, z) is computed as follows.

```x'=|Amag| *(Wx(.)A.Unitvector ());
y’=|Amag|*(Wy(.)A.UnitVector ());```

Where Wx= [1 0 0]

& Wy= [0 1 0]

& (.) is the dot product of Vectors.

Basically Wx &Wy are the Unit Vectors.

3. Perspective Projections
4. There are Three Types of Perspective Projections.

1. Single Point Perspective.
2. Two Point Perspective.
3. Three Point Perspective.

Here we are discussing only Single Point perspective. The Perspective Projection is calculated by Matrix Multiplication.

```X’=X/(rz+1);
Y’=Y/(rz+1);```

Where r= -1/Zc

& Zc is the Distance at Z Direction from the Viewing Point.

## Using the code

```class C3DCanvas : public CDC
{
CBitmap		m_bitmap;		// Offscreen bitmap
CBitmap*	m_oldBitmap;	// bitmap originally found in CMemDC
CDC*		m_pDC;			// Saves CDC passed in constructor
CRect		m_rect;			// Rectangle of drawing area.
BOOL		m_bMemDC;
CPen        m_penWhite;
CPen        *m_oldPen;
C3DVector   W_X;//(1,0,0);//Unit Vector for X Axis
C3DVector   W_Y;//(0,1,0);//Unit Vector for Y Axis
C3DVector   W_Z;//(0,0,1);//Unit Vector for Z Axis
C3DVector   m_org;

int m_winOrgX;
int m_winOrgY;
BOOL m_bPerpective;
public:
C3DVector   m_camera;
void SetCamera(double dx,double dy,double dz);
void SetWindowOrg(int x,int y);
void SetViewPortOrg(C3DVector v);
void TranslateView(C3DVector v);
void RotateView(float Angle,AXIS axis);
void Line3D(C3DVector  P,C3DVector Q);
void EnablePerspectiveView(BOOL bSet=TRUE)
{
m_bPerpective=bSet;
}
C3DCanvas(CDC* pDC, const CRect* pRect = NULL,COLORREF m_clrBkColor=0xffffff)
:CDC(),
W_X(1,0,0),
W_Y(0,1,0),
W_Z(0,0,1),
m_org(0,0,0),
m_winOrgX(0),
m_winOrgY(0),
m_camera(0,0,1000)
{
m_bPerpective=FALSE;
ASSERT(pDC != NULL);

// Some initialization
m_pDC = pDC;
m_oldBitmap = NULL;
m_bMemDC = !pDC->IsPrinting();

// Get the rectangle to draw
if (pRect == NULL) {
pDC->GetClipBox(&m_rect);
} else {
m_rect = *pRect;
}

if (m_bMemDC) {
// Create a Memory DC
CreateCompatibleDC(pDC);
pDC->LPtoDP(&m_rect);

m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
m_oldBitmap = SelectObject(&m_bitmap);

SetMapMode(pDC->GetMapMode());

SetWindowExt(pDC->GetWindowExt());
SetViewportExt(pDC->GetViewportExt());

pDC->DPtoLP(&m_rect);
SetWindowOrg(m_rect.left, m_rect.top);
} else {
// Make a copy of the relevent parts of the current DC for printing
m_bPrinting = pDC->m_bPrinting;
m_hDC       = pDC->m_hDC;
m_hAttribDC = pDC->m_hAttribDC;
}

// Fill background
FillSolidRect(m_rect, /*pDC->GetBkColor()*/m_clrBkColor);
m_penWhite.CreatePen(PS_SOLID,1,RGB(255,255,255));
m_oldPen=SelectObject(&m_penWhite);
SetTextColor(RGB(255,255,255));

}
~C3DCanvas()
{
if (m_bMemDC) {
// Copy the offscreen bitmap onto the screen.

m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
this, m_rect.left, m_rect.top, SRCCOPY);
//Swap back the original bitmap.
SelectObject(m_oldBitmap);
SelectObject(m_oldPen);
m_penWhite.DeleteObject();
} else {
// All we need to do is replace the DC with an illegal value,
// this keeps us from accidently deleting the handles associated with
// the CDC that was passed to the constructor.
m_hDC = m_hAttribDC = NULL;
}
}

C3DVector ToPerspectiveView(C3DVector v, double z);
};

//

void C3DCanvas::Line3D(C3DVector P, C3DVector Q)
{
int x1,y1,x2,y2;
P=P-m_org;
Q=Q-m_org;
double r=1;

if(m_bPerpective)
{
P=ToPerspectiveView(P,m_camera.Magnetude());
Q=ToPerspectiveView(Q,m_camera.Magnetude());
}

double dMag1=P.Magnetude();
x1=(int)( ( ( dMag1 ) * ( P.UnitVector() * W_X ) ) )-m_winOrgX;
y1=(int)( ( ( dMag1 ) * ( P.UnitVector() * W_Y ) ) )-m_winOrgY;

double dMag2=Q.Magnetude();
x2=(int)( ( ( dMag2 ) * ( Q.UnitVector() * W_X) ) )-m_winOrgX;
y2=(int)( ( ( dMag2 ) * ( Q.UnitVector() * W_Y) ) )-m_winOrgY;

MoveTo(x1,y1);
LineTo(x2,y2);
}

C3DVector C3DCanvas::ToPerspectiveView(C3DVector v, double z)
{
double r=0;

r=-1/z;
v.m_x=v.m_x/((r*v.m_z)+1);
v.m_y=v.m_y/((r*v.m_z)+1);
v.m_z=v.m_z/((r*v.m_z)+1);

return v;
}

void CMy3DTransformationsView::OnPaint()
{
CPaintDC dc(this); // device context for painting
CRect rectClient ;
GetClientRect(rectClient);
C3DCanvas canvas(&dc,&rectClient,RGB(0,0,0));
C3DVector v(-x1,-y1,-z1);
canvas.SetViewPortOrg(v);
canvas.EnablePerspectiveView(TRUE);
canvas.SetCamera(0,0,1650);
canvas.m_camera.Rotate(x,X_AXIS);
canvas.m_camera.Rotate(y,Y_AXIS);
canvas.m_camera.Rotate(z,Z_AXIS);
canvas.SetWindowOrg(-600,-300);
C3DVector v1(0,-300,0),v2(0,300,0);
CPen pen1(PS_DASHDOT,1,RGB(255,0,0));
CPen *oldPen=canvas.SelectObject(&pen1);
v1.Rotate(x,X_AXIS);
v1.Rotate(y,Y_AXIS);
v1.Rotate(z,Z_AXIS);
v2.Rotate(x,X_AXIS);
v2.Rotate(y,Y_AXIS);
v2.Rotate(z,Z_AXIS);
canvas.Line3D(v1,v2);
canvas.SelectObject(oldPen);

CPen pen2(PS_DASHDOT,1,RGB(0,255,0));
C3DVector v3(-300,0,0),v4(300,0,0);
v3.Rotate(x,X_AXIS);
v3.Rotate(y,Y_AXIS);
v3.Rotate(z,Z_AXIS);
v4.Rotate(x,X_AXIS);
v4.Rotate(y,Y_AXIS);
v4.Rotate(z,Z_AXIS);
oldPen=canvas.SelectObject(&pen2);
canvas.Line3D(v3,v4);
canvas.SelectObject(oldPen);

CPen pen3(PS_DASHDOT,1,RGB(0,0,255));
C3DVector v5(0,0,-300),v6(0,0,300);
v5.Rotate(x,X_AXIS);
v5.Rotate(y,Y_AXIS);
v5.Rotate(z,Z_AXIS);
v6.Rotate(x,X_AXIS);
v6.Rotate(y,Y_AXIS);
v6.Rotate(z,Z_AXIS);
oldPen=canvas.SelectObject(&pen3);
canvas.Line3D(v5,v6);
canvas.SelectObject(oldPen);
CPen pen4(PS_SOLID,1,RGB(122,255,255));
oldPen=canvas.SelectObject(&pen4);

C3DVector vect[8];

vect[0].m_x=50;
vect[0].m_y=50;
vect[0].m_z=50;

vect[1].m_x=250;
vect[1].m_y=50;
vect[1].m_z=50;

vect[2].m_x=50;
vect[2].m_y=250;
vect[2].m_z=50;

vect[3].m_x=250;
vect[3].m_y=250;
vect[3].m_z=50;

vect[4].m_x=250;
vect[4].m_y=250;
vect[4].m_z=250;

vect[5].m_x=50;
vect[5].m_y=250;
vect[5].m_z=250;

vect[6].m_x=250;
vect[6].m_y=50;
vect[6].m_z=250;

vect[7].m_x=50;
vect[7].m_y=50;
vect[7].m_z=250;
for(int i=0;i<8;i++)
{	vect[i].Rotate(x,X_AXIS);
vect[i].Rotate(y,Y_AXIS);
vect[i].Rotate(z,Z_AXIS);
}
canvas.Line3D(vect[0],vect[1]);
canvas.Line3D(vect[2],vect[0]);
canvas.Line3D(vect[3],vect[1]);
canvas.Line3D(vect[3],vect[2]);
canvas.Line3D(vect[3],vect[4]);
canvas.Line3D(vect[5],vect[4]);
canvas.Line3D(vect[5],vect[2]);
canvas.Line3D(vect[4],vect[6]);
canvas.Line3D(vect[7],vect[6]);
canvas.Line3D(vect[7],vect[0]);
canvas.Line3D(vect[7],vect[5]);
canvas.Line3D(vect[6],vect[1]);
canvas.SelectObject(oldPen);
}```

Enjoy 3D Vector Graphics.

## Share

No Biography provided
Group type: Organisation

2 members