|
An outline of Scientific 3D Charting and 3D Graphing with ProEssentials v6 graphing controls: .NET, ActiveX, MFC Library, VCL
The following section discusses how to create the various 3D Charts.
But before we get into the examples, there are a few topics which need
extra attention.
3D Charts Data Format
When passing data to a 3D Scientific Graph Control, the 3D Scientific Graph
can only handle data passed Subset By Point. In other words, (s0,p0)..(s0,p1)..(s0,p2)..
and so on. Look at SubsetByPoint
for the case when TRUE.
Points is related to X axis and XData. In other words, Points defines
how many polygons or 3d-bars are along the x axis. Subsets
is related to the Z axis and ZData.
In other words, Subsets defines how many polygons or 3d-bars are
long the z axis.
When passing data for surface plotting, XData should always increase
with each new point/element, and ZData should be in groups of identical
values. Note how s0 is the same element for the first three and how p0,
p1, and p2 are different for the first three.
(s0,p0)..(s0,p1)..(s0,p2)..(s0,pn)....(s1,p0)..(s1,p1)..(s1,p2)...
Always keep this in mind when building 3D surface charts.
XData should always
increase with each new point, and
ZData should be in groups
of identical values with each new point.
To further explain this requirement, note how this routine causes XData
to increase with each point, and how ZData stays the same for all points
in a subset.
|
for s = 0 to 24
for p = 0 to 24
Pe3do1.XData(s, p) = 50 + (p * 10)
'** p in formula causes XData to increment with each p
**'
Pe3do1.ZData(s, p) = 50 + (s * 50)
'** s in formula causes all points to have same ZData value
**'
Pe3do1.YData(s, p) = (35 * cos(p * .2)) * (10 * sin(s *
.34))
Next p
Next s |
For simple wire frames and solids it doesn't make much difference, but
for contour, shading, and hidden line removal logic, the order of the
points in the polygons is critical. Calculations are based on normal vectors
and vector mathematics and the order of points determines if the vector
is positive or negative.
To summarize, if your charts look fine in WireFrame or Solid form, but
look messed up in a shaded or contoured form, check that your XData increases
with each point and your ZData is in groups of identical values. Or more
simply, try switching your XData to ZData and ZData to XData.
3D Polygon Data PolyMode
This property controls the different modes in which the 3D Scientific
Graph can operate. It's recommended that the component be reset at the start
of your initialization process. You do this with a call to PEreset
(OCX/VCL developers can use PEactions = 20/xReset). Immediately after
the reset, set PolyMode as needed
and complete the rest of the initialization.
So the start of your 3D chart implementation will always begin with...
Pe3do1.PEreset
pe3do1.PolyMode = PEPM_SURFACE ' or as needed
3D Surfaces
ProEssentials can create surfaces in the following formats: WireFrame,
Solid, Shaded Solid, Contoured Solid, and Pixel. 3D Surface charts can
have a bottom or top 2D contour within the image. This contour can be
in lines or colors. See ShowContour.
3D Surface charts are produced from XData,
YData, and ZData.
Generally, X-Data and Z-Data are equally spaced but this is not mandatory.
Once you supply this data, the component will construct a list of polygons
which will produce a surface plot of the data. The following example code
shows how to construct a simple surface plot.
|
Dim s As Integer
Dim p As Integer
'** Always start with this **'
Pe3do1.PEactions = 20
Pe3do1.PolyMode = PEPM_SURFACEPOLYGONS
Pe3do1.PrepareImages = True
'** Set the amount of data and pass data **'
Pe3do1.Subsets = 15
Pe3do1.Points = 15
For s = 0 To 14
For p = 0 To 14
Pe3do1.XData(s, p) = 50 + (p * 10)
'** p in formula causes XData to increment with each p
**'
Pe3do1.ZData(s, p) = 50 + (s * 50)
'** s in formula causes all points to have same ZData value
**'
Pe3do1.YData(s, p) = (5+35*Cos(p*.4))*(5+10*Sin(s*.34))
Next p
Next s
Pe3do1.DegreeOfRotation = 55
Pe3do1.ViewingHeight = 8
Pe3do1.PlottingMethod = 2 ' surface with shading
Pe3do1.ShowContour = PESC_BOTTOMLINES
Pe3do1.ManualContourLine = 50
Pe3do1.MainTitle = "3D Example"
Pe3do1.SubTitle = ""
Pe3do1.XAxisLabel = "Points"
Pe3do1.ZAxisLabel = "Subsets"
Pe3do1.YAxisLabel = "Data value" |
The above code produces the following example image.
Notice how the first two lines reset the component and set the PolyMode
property.
The next few lines set the amount of data and pass random data into
the chart. Notice how XData increases with each data point as described
in the above Data Format section.
The control is rotated with the DegreeOfRotation
property and tilted with the ViewingHeight property. DegreeOfRotation
accepts values from 0 to 359 degrees. ViewingHeight
is basically an abstract value ranging from 50 to -50.
Next, the PlottingMethod property is set. Refer to PlottingMethod
for more information. Note that the possible PlottingMethod values change
based on the setting of PolyMode.
Contour bottom lines are added with ShowContour,
and ManualContourLine is
used to add more lines to the bottom contour.
Finally, we set some titles and labels as is done with all other ProEssentials
controls.
3D Bar Charts
ProEssentials can create 3D Bar Charts in the following formats: WireFrame,
Solid, and Shaded Solid.
Similar to the Graph control, the 3D Bar chart only needs YData.
Subsets defines how many rows are
along z axis and Points defines how
many columns are along x axis.
SubsetLabels and PointLabels
are used to label rows and columns. SubsetColors
is used to control colors of subset bars.
Once you supply the data, the control will construct a list of polygons
which will produce a 3D Bar Chart of the data. The following example code
shows how to construct a simple 3D Bar Chart.
|
Dim s As Integer
Dim p As Integer
Pe3do1.PEactions = 20
Pe3do1.PolyMode = PEPM_3DBAR
Pe3do1.PrepareImages = True
Pe3do1.Subsets = 10
Pe3do1.Points = 10
For s = 0 To 9
For p = 0 To 9
Pe3do1.YData(s, p) = (5+35*Cos(p*.4))*(5+10*Sin(s*.34))
Next p
Pe3do1.SubsetColors(s) = RGB(100+s*18, 100+s*18, 100+s*18)
Next s
Pe3do1.SubsetLabels(0) = "Hello"
Pe3do1.SubsetLabels(1) = "World"
Pe3do1.PointLabels(0) = "Texas"
Pe3do1.PointLabels(1) = "Washington"
Pe3do1.DegreeOfRotation = 309
Pe3do1.ViewingHeight = 4
Pe3do1.FontSize = PEFS_SMALL
Pe3do1.PlottingMethod = 1
Pe3do1.MainTitle = "3D Bar Chart"
Pe3do1.SubTitle = ""
Pe3do1.XAxisLabel = "Points"
Pe3do1.ZAxisLabel = "Subsets"
Pe3do1.YAxisLabel = "Data value" |
The following image was produced by the above code.
Notice the similarity in code to that of the 3D Surface plot. The only
significant differences from the previous example are...
only pass YData.
assigns custom SubsetColors
to color bars sharing same subset.
assigns a few SubsetLabels
and PointLabels. Note in the image the first two subset labels
"Hello" and "World", and first two point labels "Texas"
and "Washington"
3D Scatter Charts
The 3D scatter chart is much like a 2D scatter chart with the addition
of ZData. Each data point thus has its own XData, YData,
and ZData coordinates.
Possible plotting methods are points, lines, and points plus lines.
Theres also an Area plotting method which will produce area layers along
the z axis. This can be used to construct a Waterfall chart.
Comparison Subsets are supported in this mode. See PlottingMethod,
and PlottingMethodII, and
ComparisonSubsets.
Graph annotations are also supported in this mode. See GraphAnnotationType
and GraphAnnotationZ.
The following example code shows how to construct a simple 3D Scatter
Chart.
|
Dim s As Integer
Dim p As Integer
Pe3do1.PEactions = 20
Pe3do1.PolyMode = PEPM_SCATTER
Pe3do1.PrepareImages = True
Pe3do1.Subsets = 10
Pe3do1.Points = 10
For s = 0 To 9
For p = 0 To 9
Pe3do1.XData(s, p)=(5+35*Sin(p*.4))*(5+10*Cos(s*.34))
Pe3do1.ZData(s, p)=(5+35*Sin(p*.4))*(5+10*Sin(s*.34))
Pe3do1.YData(s, p)=(5+35*Cos(p*.4))*(5+10*Sin(s*.34))
Next p
Pe3do1.SubsetPointTypes(s) = PEPT_DOTSOLID
Next s
Pe3do1.DegreeOfRotation = 160
Pe3do1.ViewingHeight = 9
Pe3do1.FontSize = PEFS_SMALL
Pe3do1.SubsetsToLegend(0) = -1
Pe3do1.PlottingMethod = 2 'Points Plus Line
Pe3do1.MainTitle = "3D Scatter Chart"
Pe3do1.SubTitle = ""
Pe3do1.XAxisLabel = "Points"
Pe3do1.ZAxisLabel = "Subsets"
Pe3do1.YAxisLabel = "Data value" |
The following image is produced by the above code.
Again this code is very similar to the first surface plot example. The
significant differences are:
passes XData,
YData, and ZData, however, no concern is needed with respect
to the format of the data as in the 3D Surface example. The scatter chart
can plot any data point at any location.
optionally assigns custom
SubsetPointTypes so all
subsets use PEPT_DOTSOLID.
optionally disables
the legend with the SubsetsToLegend
property.
3D Polygon Data Interface
The 3D Polygon data interface allows the developer to supply their own
list of polygons to be rendered. WireFrame, Solid, and Shaded Solid images
can be produced from this data.
Its important that polygon vertices are ordered properly. The polygon
vertices must be ordered in a counter-clockwise order as viewed from outside
of the control. This is only necessary for hidden line removal and shading
purposes. If you are only producing a wireframe image, the ordering of
vertices is not critical. In the process of producing a shaded object,
and rotating this object, if you notice polygons getting darker where
they should be getting lighter, then reverse the order of the vertices
within those polygons. You should first concentrate on getting the polygons
into the object and producing a wireframe. Once the wireframe is plotting,
then look at the shaded surface during rotation and determine if vertices
need to be in a different order.
Also, note that the polygon vertices should be normalized to logical
units between -10 and 10 for all three axes.
AddSkirts should be set to TRUE
if the polygon data forms an enclosed surface and you want to produce
a surface or shaded surface image.
More than one object can be placed into 3D space, however, the objects
should not intersect.
The following example code shows how to construct a simple 3D object
using the 3D Polygon Interface. This particular example creates a pyramid
consisting of 4 polygons, each with 3 vertices.
|
Pe3do1.PEactions = 20
Pe3do1.PolyMode = PEPM_POLYGONDATA
Pe3do1.PrepareImages = True
ReDim MyPolys(4) As POLYGONDATA
'** Define first polygon **'
MyPolys(0).Vertices(0).x = 0
MyPolys(0).Vertices(0).y = -10
MyPolys(0).Vertices(0).Z = -10
MyPolys(0).Vertices(1).x = -10
MyPolys(0).Vertices(1).y = -10
MyPolys(0).Vertices(1).Z = 0
MyPolys(0).Vertices(2).x = 0
MyPolys(0).Vertices(2).y = 10
MyPolys(0).Vertices(2).Z = 0
MyPolys(0).NumberOfVertices = 3
MyPolys(0).PolyColor = RGB(128, 128, 128)
'** Define second polygon **'
MyPolys(1).Vertices(0).x = -10
MyPolys(1).Vertices(0).y = -10
MyPolys(1).Vertices(0).Z = 0
MyPolys(1).Vertices(1).x = 0
MyPolys(1).Vertices(1).y = -10
MyPolys(1).Vertices(1).Z = 10
MyPolys(1).Vertices(2).x = 0
MyPolys(1).Vertices(2).y = 10
MyPolys(1).Vertices(2).Z = 0
MyPolys(1).NumberOfVertices = 3
MyPolys(1).PolyColor = RGB(128, 128, 128)
'** Define third polygon **'
MyPolys(2).Vertices(0).x = 0
MyPolys(2).Vertices(0).y = -10
MyPolys(2).Vertices(0).Z = 10
MyPolys(2).Vertices(1).x = 10
MyPolys(2).Vertices(1).y = -10
MyPolys(2).Vertices(1).Z = 0
MyPolys(2).Vertices(2).x = 0
MyPolys(2).Vertices(2).y = 10
MyPolys(2).Vertices(2).Z = 0
MyPolys(2).NumberOfVertices = 3
MyPolys(2).PolyColor = RGB(128, 128, 128)
'** Define fourth polygon **'
MyPolys(3).Vertices(0).x = 10
MyPolys(3).Vertices(0).y = -10
MyPolys(3).Vertices(0).Z = 0
MyPolys(3).Vertices(1).x = 0
MyPolys(3).Vertices(1).y = -10
MyPolys(3).Vertices(1).Z = -10
MyPolys(3).Vertices(2).x = 0
MyPolys(3).Vertices(2).y = 10
MyPolys(3).Vertices(2).Z = 0
MyPolys(3).NumberOfVertices = 3
MyPolys(3).PolyColor = RGB(128, 128, 128)
'** Pass the polygon data into object **'
Call PEvset(Pe3do1, PEP_structPOLYDATA, MyPolys(0), 4)
Pe3do1.DegreeOfRotation = 160
Pe3do1.ViewingHeight = 19
Pe3do1.FontSize = PEFS_SMALL
Pe3do1.PlottingMethod = 2 'Solid Shading
Pe3do1.MainTitle = "3D Object Chart"
Pe3do1.SubTitle = ""
Pe3do1.ShowXAxis = PESA_EMPTY
Pe3do1.ShowYAxis = PESA_EMPTY
Pe3do1.ShowZAxis = PESA_EMPTY
Pe3do1.ShowBoundingBox = PESBB_ALWAYS |
The above code produces the following image.
Note how the vertices values range from -10 to 10.
Note the use of PEvset to transfer the polygon data into the control.
Note how ShowXAxis, ShowYAxis,
and ShowZAxis are used to hide the
axes of the chart.
Finally, ShowBoundingBox
is used to add a bounding box to image.
|