Click here to Skip to main content
15,867,594 members
Articles / Desktop Programming / ATL
Article

3D Graph ActiveX Control

Rate me:
Please Sign up or sign in to vote.
4.90/5 (100 votes)
2 Aug 2003MIT3 min read 767K   50K   284   111
An ATL/STL ActiveX control based on OpenGL library for 3D data visualization

NTGraph3D -Sample Image

Introduction

This is an ActiveX control based on the OpenGL library, which allows you to plot three-dimensional data. The control is entirely written on ATL/STL, and does not link to MFC libraries.

The control can perform the following functions:

  • Axis customization, including customizable font, colors, and titles.
  • Plot a large number of points and updating one or more plots on the graph with new data, replacing the old plot with the new plot.
  • Plot the multiple elements with individual properties such as line and point color, line width, and point size.
  • Lighting
  • Plot styles: {0 (Lines); 1 (Points); 2 (LinePoint); 3 (Surface)}
  • By setting the Projection property you should be able to change the viewing to: (0) Perspective (in which objects that are closer appear larger), and (1) Orthographic (in which the sizes and angles between objects are maintained no matter what their distance from the viewer).
  • By setting the TrackMode property you should be able to do: (1) Zooming, (2) Rotation, and (3) Panning at runtime.

About the Code

To use this control, embed it in an application that supports the use of ActiveX controls. Microsoft Visual Basic applications, all MS Office applications, VBScript and JavaScript in the HTA or Internet Explorer applications, and applications created with the Microsoft Developer Studio’s AppWizard can support the use of ActiveX controls.

Before you start, the control must be register as a COM component using Regsvr32.exe. Regsvr32 takes one argument the DLL or control to register and any of several command-line switches, the most notable of which is /u to uninstall a control. By default that is, when run with only a dll or ocx Regsvr32.exe registers the control.

Note: you must do this on every computer that you are going to use the control!

For more information on how to register and how to include the control in a VC Project, refer to my article 2D Graph ActiveX Control.

Bellow are two listings that demonstrates how to use the control to draw a Torus:

C++

C++
//
//
// Plot Torus
//
void CDemoDlg::OnButton1() 
{
   m_Graph3D.SetCaption ("Torus");
   m_Graph3D.ClearGraph(); // Clear all data
   m_Graph3D.AddElement(); // Add an element to element list

   m_Graph3D.SetElementLineColor(0, RGB(255,0,0));
   m_Graph3D.SetElementType(0, 3); // draw surface
   
   double x,y,z,ti,tj;
   
   for (int i = 0; i < 41; i++)
   {
      ti = (i - 20.0)/20.0 * 3.15;
      
      for (int j = 0; j < 41 ; j++) 
      {
	   tj = (j - 20.0)/20.0 * 3.15;
           
	   x = (cos(tj) + 3.0) * cos(ti);
	   y = sin(tj);
	   z = (cos(tj) + 3.0) * sin(ti);

           m_Graph3D.PlotXYZ(x,y,z,0); 
     }
   }

   //m_Graph3D.SetRange (-4, 4, -1, 1, -4, 4);
   m_Graph3D.AutoRange();
}

Visual Basic

VBScript
'''''''''''''''''''''''''''''' 
' Look at the Demo3D.hta file 
' Double click on file to start the demo
'
' Plot Torus
'
Sub Torus

   With Graph3D
	.ClearGraph
  	.AddElement
        .Caption = "Torus"
	.ElementType(0) = 3 'Draw Surface

   For i = 0 To 41
    ti = (i - 20.0)/20.0 * 3.15

    For j = 0 To 41 
	
	tj = (j - 20.0)/20.0 * 3.15

	x = (cos(tj) + 3.0) * cos(ti)
	y = sin(tj)
	z = (cos(tj) + 3.0) * sin(ti)
	.PlotXYZ x,y,z,0
        
     Next
    Next
    	.Autorange
  End With
End Sub

List of Control Properties:

    Graph

  •  short Appearance
  •  long BorderStyle
  •  VARIANT_BOOL BorderVisible
  •  BSTR Caption
  •  IFontDisp* Font
  •  OLE_COLOR BackColor
  •  OLE_COLOR CaptionColor
  •  short TrackMode
  •  short Projection
  •  BSTR XLabel
  •  BSTR YLabel
  •  BSTR ZLabel
  •  short XGridNumber
  •  short YGridNumber
  •  short ZGridNumber
  •  OLE_COLOR XGridColor
  •  OLE_COLOR YGridColor
  •  OLE_COLOR ZGridColor

    Elements

  •  OLE_COLOR ElementLineColor(long ElementID, OLE_COLOR newVal)
  •  OLE_COLOR ElementPointColor(long ElementID, OLE_COLOR newVal)
  •  float ElementLineWidth(long ElementID, float newVal)
  •  float ElementPointSize(long ElementID, float newVal)
  •  short ElementType(long ElementID)
  •  BOOL ElementShow(long ElementID)
  •  BOOL ElementSurfaceFill(long ElementID)
  •  BOOL ElementSurfaceFlat(long ElementID)
  •  BOOL ElementLight(long ElementID
  •  short ElementLightingAmbient(long ElementID)
  •  short ElementLightingDiffuse(long ElementID)
  •  short ElementLightingSpecular(long ElementID)
  •  short ElementMaterialAmbient(long ElementID)
  •  short ElementMaterialDiffuse(long ElementID)
  •  short ElementMaterialSpecular(long ElementID)
  •  short ElementMaterialShinines(long ElementID)
  •  short ElementMaterialShinines(long ElementID)
  •  short ElementMaterialEmission(long ElementID)

List of Control Methods:

    Graph

  •  void SetRange(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax)
  •  void AutoRange()
  •  void ShowPropertyPages()

    Elements

  •  void AddElement()
  •  void DeleteElement(long ElementID)
  •  void ClearGraph()
  •  void PlotXYZ(double x, double y, double z, long ElementID)
  •  void SetLightCoordinates(long ElementID, float x, float y, float z)

Cost: One bottle wine. :-)

Enjoy!

Note: I am not expert on OpenGL, therefore all good suggestions, code and help for imporving the control are welcome!

Send mail to nteofilov@yahoo.de with questions or comments about this article.

History

16 Jun 2003 - v1.0 Initial release

22 Jun 2003 - v2.0

  • Thanks to Alexander Chernosvitov for the Excellent article Function graphics in 3D.
  • Lot’s of new properties (see property list and demo files)
  • ElementType = {0 (Lines); 1 (Points); 2 (LinePoint); 3 (Surface)}
  • Added new demo file that demonstrate the new features
  • New Property BOOL ElementShow(long ElementID)
29 Jul 2003 - v2.1
  • Some drawing fixes
  • Added CopyToClipboard (Works only with release versions of the control! )
  • Added Klein Bottle
  • Changes to the Demo Projects

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Researcher
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionUnable to run Demo project Pin
NKiKiN16-Jul-23 21:04
NKiKiN16-Jul-23 21:04 
QuestionMy vote of 5 Pin
nilaysoft5-Oct-16 2:53
nilaysoft5-Oct-16 2:53 
GeneralMy vote of 2 Pin
John Smith 12312314-Feb-14 6:06
John Smith 12312314-Feb-14 6:06 
QuestionLline color rainbow Pin
mahcyp27-Nov-11 7:07
mahcyp27-Nov-11 7:07 
AnswerRe: Lline color rainbow Pin
zhaojianzhong12-Aug-12 22:55
zhaojianzhong12-Aug-12 22:55 
GeneralMy vote of 2 Pin
ibyk3015-Jun-11 14:25
ibyk3015-Jun-11 14:25 
GeneralRe: My vote of 2 Pin
xrg_soft@163.com28-Jun-11 23:28
xrg_soft@163.com28-Jun-11 23:28 
GeneralRe: My vote of 2 Pin
elha5818-Oct-11 22:18
elha5818-Oct-11 22:18 
Questionsetting element color Pin
ibyk3030-May-11 7:02
ibyk3030-May-11 7:02 
GeneralMy vote of 5 Pin
RedDk15-Apr-11 8:39
RedDk15-Apr-11 8:39 
Questionvisual studio 2010 ? Pin
roboticEDAR29-Mar-11 10:45
roboticEDAR29-Mar-11 10:45 
AnswerRe: visual studio 2010 ? Pin
Member 1316019629-Apr-17 0:58
Member 1316019629-Apr-17 0:58 
QuestionIs the src project is supposed to generate an ActiveX control ? Pin
Michael B Pliam31-Jan-11 11:47
Michael B Pliam31-Jan-11 11:47 
AnswerRe: Is the src project is supposed to generate an ActiveX control ? Pin
Michael B Pliam26-Feb-11 9:01
Michael B Pliam26-Feb-11 9:01 
QuestionWould be nice if this were NOT an ActiveX Control ? Pin
Michael B Pliam30-Jan-11 20:34
Michael B Pliam30-Jan-11 20:34 
AnswerRe: Would be nice if this were NOT an ActiveX Control ? Pin
nguyenvanhauk510-Jul-12 20:41
nguyenvanhauk510-Jul-12 20:41 
GeneralUsing this library in C++ Pin
Vi_Ter5-Oct-09 4:40
Vi_Ter5-Oct-09 4:40 
Generalgetting errors for data types(error: C2664) Pin
hituhoney16-Jul-09 2:16
hituhoney16-Jul-09 2:16 
GeneralRe: getting errors for data types(error: C2664) Pin
Member 389846914-Nov-09 4:52
Member 389846914-Nov-09 4:52 
GeneralOpen GL Pin
Myron Langer16-Apr-09 6:32
Myron Langer16-Apr-09 6:32 
GeneralRe: Open GL Pin
ibyk301-Jun-11 5:05
ibyk301-Jun-11 5:05 
download NTGraph3D demo, extract files and double click on Demo3D.hta to see it run in a browser.
you can open same file and code is nearly identical to VB, so you can simply copy and paste.

of course you need to create new VB application (standard EXE) and add reference (Ctrl+T) to NTGraph after registering ntgraph3d.dll.
this will allow you to drop new NTGraph control onto VB form.

can't post file but here is entire form of VB6 demo version.

VERSION 5.00
Object = "{7A99C13D-22DF-400C-AB37-48C32A897EFB}#1.0#0"; "ntgraph3d.dll"
Begin VB.Form Form1
Caption = "ibyk30 : NTGraph3D demo in VB6"
ClientHeight = 11850
ClientLeft = 60
ClientTop = 345
ClientWidth = 18495
LinkTopic = "Form1"
ScaleHeight = 11850
ScaleWidth = 18495
StartUpPosition = 3 'Windows Default
Begin VB.Frame Frame1
Caption = "Track Mode"
Height = 2415
Left = 17160
TabIndex = 5
Top = 3840
Width = 1215
Begin VB.OptionButton radTrackModeRotate
Caption = "Rotate"
Height = 495
Left = 120
TabIndex = 9
Top = 1200
Width = 975
End
Begin VB.OptionButton radTrackModePan
Caption = "Pan"
Height = 495
Left = 120
TabIndex = 8
Top = 1680
Width = 975
End
Begin VB.OptionButton radTrackModeZoom
Caption = "Zoom"
Height = 375
Left = 120
TabIndex = 7
Top = 840
Width = 855
End
Begin VB.OptionButton radTrackModeLock
Caption = "Lock"
Height = 375
Left = 120
TabIndex = 6
Top = 360
Value = -1 'True
Width = 975
End
End
Begin VB.CommandButton btnKlein
Caption = "Klein Bottle"
Height = 615
Left = 17160
TabIndex = 4
Top = 2280
Width = 1215
End
Begin VB.CommandButton btnSine
Caption = "Sine"
Height = 615
Left = 17160
TabIndex = 3
Top = 1560
Width = 1215
End
Begin VB.CommandButton btnButterfly
Caption = "Butterfly"
Height = 615
Left = 17160
TabIndex = 2
Top = 840
Width = 1215
End
Begin VB.CommandButton btnTorus
Caption = "Torus"
Height = 615
Left = 17160
TabIndex = 1
Top = 120
Width = 1215
End
Begin NTGRAPH3DLibCtl.NTGraph3D NTGraph3D
Height = 11655
Left = 120
OleObjectBlob = "Form1.frx":0000
TabIndex = 0
Top = 120
Width = 16815
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Dim i As Integer
Dim j As Integer
Dim ti As Double
Dim tj As Double
Dim x As Double
Dim y As Double
Dim z As Double
Dim csv(800, 1024) As Single

Private Sub btnTorus_Click()
With NTGraph3D
.ClearGraph
.AddElement
.Caption = "Torus"
.ElementType(0) = 3 'Draw Surface

For i = 0 To 40
ti = (i - 20) / 20 * 3.15

For j = 1 To 41
tj = (j - 20) / 20 * 3.15

x = (Cos(tj) + 3) * Cos(ti)
y = Sin(tj)
z = (Cos(tj) + 3) * Sin(ti)
.PlotXYZ x, y, z, 0

Next
Next
.AutoRange
End With
End Sub

Private Sub btnSine_Click()
With NTGraph3D
.ClearGraph
.AddElement
.Caption = "Double Sine"
For i = 0 To 40
x = ((i - 20) / 20) * 3.15

For j = 0 To 40

NTGraph3D.AddElement

z = ((j - 20) / 20) * 3.15

y = Sin(x) * Cos(z) + 2

NTGraph3D.ElementType(j) = 0
NTGraph3D.ElementLineColor(i) = RGB(255, 0, 0)
NTGraph3D.PlotXYZ x, y, z, j

Next
Next

.AutoRange
End With
End Sub

Private Sub btnButterfly_Click()
Dim hold1 As Double
Dim holdm As Double
With NTGraph3D
.Caption = "Butterfly"
.ClearGraph
.AddElement
.ElementType(0) = 3

For i = 0 To 41
ti = (i - 20) / 20 * 3.15
For j = 0 To 41
tj = (j - 20) / 20 * 3.15
hold1 = Sin(tj)
holdm = Cos(ti * 0.5) * hold1 - Sin(ti * 0.5) * Sin(tj * 2)

x = holdm * Cos(ti)
y = holdm * Sin(ti) * 0.5
z = Sin(ti * 0.5) * hold1 + Cos(ti * 0.5) * Sin(tj * 0.5)
.PlotXYZ x, y, z, 0
Next
Next
.AutoRange
End With
End Sub

Private Sub btnKlein_Click()

Dim u As Double
Dim v As Double
Dim rad As Double
Dim Bx As Double
Dim By As Double
Dim Pi As Double

With NTGraph3D
.Caption = "Klein Bottle"
.ClearGraph
.AddElement
.ElementPointColor(0) = RGB(0, 0, 255)
.ElementType(0) = 1

'Generate data to plot

Pi = 3.14

For u = 0 To 2 * Pi Step 0.1
For v = 0 To 2 * Pi Step 0.1

Bx = 6 * Cos(u) * (1 + Sin(u))
By = 16 * Sin(u)

rad = 4 * (1 - Cos(u) / 2)

If Pi < u And u <= 2 * Pi Then
x = Bx + rad * Cos(v + Pi)
Else
x = Bx + rad * Cos(u) * Cos(v)
End If

If Pi < u And u <= 2 * Pi Then
y = By
Else
y = By + rad * Sin(u) * Cos(v)
End If

z = rad * Sin(v)

.PlotXYZ x, y, z, 0
Next
Next
.AutoRange
End With
End Sub

' radio buttons to select tracking mode
Private Sub radTrackModeLock_Click()
NTGraph3D.TrackMode = 0 ' Lock
End Sub

Private Sub radTrackModeZoom_Click()
NTGraph3D.TrackMode = 1 ' Zoom
End Sub

Private Sub radTrackModeRotate_Click()
NTGraph3D.TrackMode = 2 ' Rotate
End Sub

Private Sub radTrackModePan_Click()
NTGraph3D.TrackMode = 3 ' Pan
End Sub

'----------------------------------------------------

If you don't really care about OpenGL and just need to plot something that looks 3D,
here is simple alternative. this code uses just series of lines drawn on a form
or Picturebox to present sort of landscape.
i don't recall where i saw the original code but here is modified version.
it allows simple scale and rotation of the plot.


Option Explicit
' based on some code sample from web, don't recall URL
Const PI = 3.14159265
Dim byaLandscape(800, 255) As Integer ' can be single as well as long as DrawLandscape datasource type is changed too

'Direct draw onto a form or picture box
Private Sub DrawLandscape(disp As Object, datasource() As Integer, PosX As Integer, PosY As Integer, TiltX As Single, TiltY As Single, XYRatio As Single, XYScale As Single)
Dim X As Integer, Y As Integer, Xplot As Integer, Yplot As Integer, yOffset As Single
disp.Cls
disp.AutoRedraw = True
disp.ScaleMode = 3 '3 = Pixels
For Y = UBound(datasource, 2) To LBound(datasource, 2) Step -1
yOffset = Y - 0.5 * UBound(datasource, 2)
For X = LBound(datasource, 1) To UBound(datasource, 1)
Xplot = PosX + CInt(XYScale * (XYRatio * X - TiltX * yOffset))
Yplot = PosY + 0.5 * UBound(datasource, 2) - CInt(XYScale * TiltY * yOffset)
If datasource(X, Y) <> 0 Then
disp.Line (Xplot, Yplot)-(Xplot, Yplot - datasource(X, Y)), RGB(Y * (255 / UBound(datasource, 2)), _
255 - (Y * (255 / UBound(datasource, 2))), _
X * (255 / UBound(datasource, 1)))
End If
Next
Next
End Sub


Private Sub Command1_Click()
' DrawLandscape Picture1, byaLandscape, CInt(Me.Text1.Text), CInt(Me.Text2.Text), Val(Me.Text3.Text), Val(Me.Text4.Text), Val(Me.Text5.Text), Val(Me.Text6.Text)
DrawLandscape Me, byaLandscape, CInt(Me.Text1.Text), CInt(Me.Text2.Text), Val(Me.Text3.Text), Val(Me.Text4.Text), Val(Me.Text5.Text), Val(Me.Text6.Text)
End Sub


Private Sub Form_Load()
'This will create data a sort of wavy landscape
Dim X As Integer, Y As Integer
For X = LBound(byaLandscape, 1) To UBound(byaLandscape, 1)
For Y = LBound(byaLandscape, 2) To UBound(byaLandscape, 2)
byaLandscape(X, Y) = 48 + (Sin((X + Y) * PI / 127) * Sin(Y * PI / 127)) * 32
Next
Next
End Sub
GeneralRe: Open GL Pin
ibyk301-Jun-11 5:26
ibyk301-Jun-11 5:26 
GeneralUsing this library in С# Pin
getbraine20-Feb-09 23:42
getbraine20-Feb-09 23:42 
GeneralRe: Using this library in С# Pin
maslbl425-Aug-10 4:51
maslbl425-Aug-10 4:51 
GeneralRe: Using this library in С# Pin
roboticEDAR29-Mar-11 10:34
roboticEDAR29-Mar-11 10:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.