13,350,047 members (47,701 online)
alternative version

#### Stats

71.8K views
46 bookmarked
Posted 6 Jun 2005

# 3DStatic

, 6 Jun 2005
 Rate this:
An article to draw a 3D math function on a static control.

## Introduction

I wanted to draw a 3D math function on a static control like "MatLab" does. Finally, I found a solution.

Consider that you want to plot a 3D Pixel Q (a,b,c) on a plane with X and Y directions. In (figure 1), I illustrate this. At first, you must move in X direction from O to P1. It is important to know |P1 O| = b. Then you must move in Y direction from P1 to P2 and |P2 P1| = c. Now you must move in 't' direction from P2 to Q. And |Q P2 | = a. In 3D space, 't' direction is X-axis, X direction is Y-axis, and Y direction is Z-axis.

Figure 1 – Plot a 3D Point on a 2D page.

We want to obtain Q(x,y), so …

Eq. 1

## Using the code

First of all, add 3DStatic.h and 3DStatic.cpp files to your project. Select Resource tab from Workspace window, and select your dialog that you want to add a display static. Select Static Control from Control toolbox and draw it on the dialog (Figure 2). Change its ID from `IDC_STATIC` to `IDC_MyStatic`.

Now it's time to add a member variable to your dialog class. Call Class Wizard to do it for you. Figure 3 shows you how to do it. In this case, we add a member variable `m_MyStatic` with type `CStatic`.

```// 3DFunctionDlg.h : header file
//

#if !defined(AFX_2DFUNCTIONDLG_H__D5D048D5_079A_
40BD_86A0_32A26253D2E5__INCLUDED_)
#define AFX_2DFUNCTIONDLG_H__D5D048D5_079A_40BD_
86A0_32A26253D2E5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "3DStatic.h"
///////////////////////////////////////////////////////////
// C2DFunctionDlg dialog

class CMy3DPageDlg : public CDialog
{
// Construction
public:
CMy3DPageDlg(CWnd* pParent = NULL);  // standard constructor

// Dialog Data
//{{AFX_DATA(CMy3DPageDlg)
enum { IDD = IDD_MY3DPage_DIALOG };
C3DStatic  m_MyStatic;    //We change it from CStatic m_MyStatic;
//to C3DStatic m_MyStatic;
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMy3DPageDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);
// DDX/DDV support
//}}AFX_VIRTUAL

// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(C2DFunctionDlg)
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations
// immediately before the previous line.

#endif // !defined(AFX_My3DPageDLG_H__D5D048D5_079A_40BD_
//86A0_32A26253D2E5__INCLUDED_)```

## How does it work?

One of the important functions is `Set3DPixel`.This function changes a point in 3D space to a 2D point. It is a polymorphism function and in its second form, it plots the obtained point on static. It uses equation 1.

```CPoint C3DStatic::Set3DPixel(C3DStatic::C3DPoint pPixel)
{
//    x=lenght ; in t Direction |P2 Q|
//    y=b ; in X Direction |OP1|
//    z=c ; in Y Direction |P1 P2|

//    newX=b-+lcos(isteep)
//    newY=newX*tan(isteep)+c-b*tan(isteep)
//    so...

CPoint newP;

float newX,newY;

CString aa;

newX=pPixel.y-pPixel.x*cos(iSteep);
newY=newX*tan(iSteep)+(pPixel.z-pPixel.y*tan(iSteep));

crColor=Set3DColor(pPixel.z);

if ((newX<=pPixel.y && pPixel.x>=0) || (newX>=pPixel.y && pPixel.x<0))
{
newP=GetNewPixel(newX,newY);
return newP;
}
else
{
newX=pPixel.y+pPixel.x*cos(iSteep);
newY=newX*tan(iSteep)+(pPixel.z-pPixel.y*tan(iSteep));
if ((newX<=pPixel.y && pPixel.x>=0) || (newX>=pPixel.y &&
pPixel.x<0))
{
newP=GetNewPixel(newX,newY);
return newP;
}
}```
```C3DStatic::Set3DPixel(CDC* pDC,C3DStatic::C3DPoint pPixel,COLORREF crColor)
{
//    x=l
//    y=A
//    z=B
// newX=A-+lcos(isteep)
// newY=newX*tan(isteep)+B-A*tan(isteep)
//  so...

CPoint newP,oldP;
float newX,newY;

CString aa;

CPen pen (PS_SOLID, 1, crColor);
pDC->SelectObject (&pen);

newX=pPixel.y-pPixel.x*cos(iSteep);
newY=newX*tan(iSteep)+(pPixel.z-pPixel.y*tan(iSteep));

if ((newX<=pPixel.y && pPixel.x>=0) || (newX>=pPixel.y && pPixel.x<0))
{
newP=GetNewPixel(newX,newY);
if ((newP.x>=0 && newP.y<=0) && (newP.x<=stcWidth && newP.y>=-stcHeight) )
pDC->SetPixel(newP,crColor);
}
else
{
newX=pPixel.y+pPixel.x*cos(iSteep);
newY=newX*tan(iSteep)+(pPixel.z-pPixel.y*tan(iSteep));
if ((newX<=pPixel.y && pPixel.x>=0) || (newX>=pPixel.y && pPixel.x<0))
{
newP=GetNewPixel(newX,newY);
if ((newP.x>=0 && newP.y<=0) &&
(newP.x<=stcWidth && newP.y>=-stcHeight))
pDC->SetPixel(newP,crColor);
}
}
}```

`C3DPoint` is a structure with three member variables `x`, `y`, `z` to get a point in three dimensions.

```struct C3DPoint
{
float   x;
float   y;
float   z;
};
```

The next function is `SetXSteep`: this function sets a steep for X axis in 3D space. `iSteep` must be set before using the function `Set3DPixel`. The next function is `GetNewPixel`:

```CPoint C3DStatic::GetNewPixel(float Oldx,float Oldy)
{
CPoint NewPoint;

NewPoint.x=int((stcWidth/(x_Max-x_Min))*Oldx-((stcWidth*x_Min)/(x_Max- x_Min)));
NewPoint.y=int(stcHeight/(y_Max-y_Min)*Oldy-(stcHeight*y_Max)/(y_Max- y_Min));

return NewPoint;
}```

This function gets a `CPoint` variable in the Static scale. The static maximum and minimum value can be obtained by using this code:

```CRect rect;
GetClientRect (&rect);
stcWidth=rect.Width();
stcHeight=rect.Height();```

In the constructor function, we can set a virtual scale for static width by defining `x_Max` and `x_Min`, and for static height by defining `y_Max` and `y_Min`. Note that variable `Oldx` must be between `x_Min` and `y_Min` and similarly for `Oldy`.

The most important part of the code is below:

```for (j=y_Min;j<=y_Max;j+=(x_Max-x_Min)/500)
for (i=x_Min;i<=x_Max;i+=(x_Max-x_Min)/500)
{
_3DPixel.z=MathFunc(j,i);

if (_3DPixel.z>=MAXp)        MAXp=_3DPixel.z;
if (_3DPixel.z<=MINp)        MINp=_3DPixel.z;

}
SetHighLowColor(MAX,MIN);

for (j=y_Min+.5;j<=y_Max;j+=(y_Max-y_Min)/2000)
for (i=x_Min+.5;i<=x_Max;i+=(x_Max-x_Min)/2000)
{
_3DPixel.y=i;
_3DPixel.x=j;
_3DPixel.z=MathFunc(j,i);
crColor=Set3DColor(_3DPixel.z);
Set3DPixel(&dc,_3DPixel,crColor);
}```

Function `MathFunc` is a math function. In this example, we have:

```float C3DStatic::MathFunc(float x,float y)
{
return 2*sin(x*y/3);
}```

The two next functions are `SetHighLowColor` and `Set3DColor`. The first attributes maximum value of `MyFunc (MAXp)` to pure red color and minimum value of `MyFunc (MINp)` to pure blue color. The second one sets a color for a given value of `Mathfunc`. Finally using `Set3DPixel`, we plot a pixel on the static.

Have fun.

A list of licenses authors might use can be found here

## Share

 Web Developer Iran (Islamic Republic of)
I live in Iran . I started hardware programming when I was young. I designed and built some ISA cards for attaching to PC.like ocsiloscope and signal generator. Now I am working for a engineering company and Manager of some project.

## You may also be interested in...

 First Prev Next
 My 5 Amir Mahfoozi19-Dec-11 2:13 Amir Mahfoozi 19-Dec-11 2:13
 Again ... M. Bonvari9-Jun-05 4:48 M. Bonvari 9-Jun-05 4:48
 I like your work! here goes my 5. thanks for informing! take care.
 Re: Again ... asef10-Jun-05 18:41 asef 10-Jun-05 18:41
 The working is exemplary, ... WREY8-Jun-05 7:30 WREY 8-Jun-05 7:30
 Re: The working is exemplary, ... Anonymous8-Jun-05 20:53 Anonymous 8-Jun-05 20:53
 Super Georgi Petrov7-Jun-05 8:38 Georgi Petrov 7-Jun-05 8:38
 Re: Super asef7-Jun-05 18:48 asef 7-Jun-05 18:48
 Re: Super Anonymous7-Jun-05 21:28 Anonymous 7-Jun-05 21:28
 Re: Super asef8-Jun-05 0:38 asef 8-Jun-05 0:38
 Re: Super Rick York25-Jun-05 11:04 Rick York 25-Jun-05 11:04
 Re: Super Georgi Petrov19-Jul-05 11:33 Georgi Petrov 19-Jul-05 11:33
 Re: Super asef22-Jul-05 20:37 asef 22-Jul-05 20:37
 Re: Super Georgi Petrov29-Jul-05 1:33 Georgi Petrov 29-Jul-05 1:33
 Excellent! A. Riazi6-Jun-05 22:03 A. Riazi 6-Jun-05 22:03
 Re: Excellent! asef6-Jun-05 22:07 asef 6-Jun-05 22:07
 Re: Excellent! Majid Shahabfar7-Jun-05 4:04 Majid Shahabfar 7-Jun-05 4:04
 Re: Excellent! asef7-Jun-05 18:42 asef 7-Jun-05 18:42
 Last Visit: 31-Dec-99 19:00     Last Update: 19-Jan-18 4:30 Refresh 1