Page 1 of 1

Making Isometric 3d grapsh

Posted: Mon Jun 09, 2008 4:12 am
by 15049124
How can I do an isometric 3d Graph.

Is any way to attach files ?

Posted: Mon Jun 09, 2008 7:07 am
by narcis
Hi QuijoteMX,

You can do something as in the All Features\Welcome!\Axes\Isometric Axes example at the features demo, available at TeeChart's program group.

You can post your files at news://www.steema.net/steema.public.attachments newsgroup or at our upload page.

Isometric axis

Posted: Tue Jun 10, 2008 1:22 am
by 15049124
Thank you for your response.

I'm using .SetIsometric .Left.Index, .Bottom.Index; but what about the third axis, right depth for instance. My problem is a 3d box drawing where the depth dimension does'nt look proportional to others.

SetIsometric method works just for 2d graphs isn't it?

Posted: Tue Jun 10, 2008 9:44 am
by narcis
Hi QuijoteMX,

Yes, but you could try implementing your own MakeIsoAxis method as shown here adding support for depth axis.

3D ISOMETRIC AXIS

Posted: Tue Jun 10, 2008 12:26 pm
by 15049124
Hi Narcis!

I'm working in VB6, the code you have sent is in C isn't it? Could it be converted almost as is or there are some issues that are diferent?

Besides, the setIsometric method provided by tChart works on left and bottom axes. The procedure you are referring to does the same. What about the depth axis.

Posted: Tue Jun 10, 2008 2:14 pm
by narcis
Hi QuijoteMX,

No, that code is in Delphi but there shouldn't be much problems porting it to VB6.

Yes, SetIsometric only uses horizontal and vertical axes (by default left and bottom), you should add support for depth axis here.

If you have any problem porting the code please let us know.

Isometric axis 3D

Posted: Wed Jun 11, 2008 1:37 am
by 15049124
Hi Narcis!

I'm having problems port the code to vb6. What´s the function getDeviceCaps?

The concept is clear making Left (y's) and bottom (x's) axis isometric. But what screen.dimension would apply for the depth(z's) axis.

Have you done something alike before? (3D isometric axis)

Posted: Thu Jun 12, 2008 8:18 am
by yeray
Hi QuijoteMX,

Could you try the following code? It seems to work fine here. And please, feel free to suggest any improving modification.

Code: Select all

Option Explicit

Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
       
Private Const HORZSIZE = 4
Private Const VERTSIZE = 6

Private Sub Command1_Click()
   MakeIsoAxis TChart1
End Sub

Private Sub Form_Load()
Dim x, z As Integer
  ScaleMode = vbPixels
  
  TChart1.Aspect.Chart3DPercent = 100
  TChart1.Legend.Visible = False
  
  TChart1.AddSeries scSurface
  
  With TChart1.Axis.Left
    .GridPen.Style = psSolid
    .GridPen.Color = vbBlack
    .Increment = 50
    .Labels.Separation = 0
  End With

  With TChart1.Axis.Bottom
    .GridPen.Style = psSolid
    .GridPen.Color = vbBlack
    .Increment = 50
    .Labels.Separation = 0
  End With
  
  With TChart1.Axis.Depth
    .Visible = True
    .GridPen.Style = psSolid
    .GridPen.Color = vbBlack
    .Increment = 50
    .Labels.Separation = 0
  End With

  For x = 1 To 50
    For z = 1 To 50
      TChart1.Series(0).asSurface.AddXYZ x, Rnd * 50, z, "", clTeeColor
    Next z
  Next x
End Sub


Private Sub MakeIsoAxis(AChart As TChart)
Dim tmpX, tmpY, tmpZ, XRange, YRange, ZRange, Offset, XYScreen As Double
  With AChart
    If (.ChartHeight > 0) And (.ChartWidth > 0) Then
      With .Axis.Bottom
        XRange = .Maximum - .Minimum
      End With
      
      With .Axis.Left
        YRange = .Maximum - .Minimum
      End With
      
      
      With .Axis.Depth
        ZRange = .Maximum - .Minimum
      End With

      XYScreen = (GetDeviceCaps(.Canvas.HandleDC, HORZSIZE) / Screen.Width) / (GetDeviceCaps(.Canvas.HandleDC, VERTSIZE) / Screen.Height)

      tmpX = (XRange / .ChartWidth)
      tmpY = (YRange / .ChartHeight) * XYScreen
      tmpZ = (ZRange / (.Axis.Depth.IEndPos - .Axis.Depth.IStartPos)) * XYScreen / 2

      If tmpX > tmpY And tmpX > tmpZ Then
        If tmpY <> 0 Then
          Offset = ((YRange * tmpX / tmpY) - YRange) / 2

          With .Axis.Left
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If

        If tmpZ <> 0 Then
          Offset = ((ZRange * tmpX / tmpZ) - ZRange)

          With .Axis.Depth
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If
      Else
        If tmpY > tmpX And tmpY > tmpZ Then
          If tmpX <> 0 Then
            Offset = ((XRange * tmpY / tmpX) - XRange) / 2

            With .Axis.Bottom
              .SetMinMax .Minimum - Offset, .Maximum + Offset
            End With
          End If

          If tmpZ <> 0 Then
            Offset = ((ZRange * tmpY / tmpZ) - ZRange)

            With .Axis.Depth
              .SetMinMax .Minimum - Offset, .Maximum + Offset
            End With
          End If
        Else
          If tmpX <> 0 Then
            Offset = ((XRange * tmpZ / tmpX) - XRange) / 2

            With .Axis.Bottom
              .SetMinMax .Minimum - Offset, .Maximum + Offset
            End With
          End If

          If tmpY <> 0 Then
            Offset = ((YRange * tmpZ / tmpY) - YRange) / 2

            With .Axis.Left
              .SetMinMax .Minimum - Offset, .Maximum + Offset
            End With
          End If
        End If
      End If
    End If
  End With
End Sub

3D ISOMETRIC AXIS

Posted: Fri Jun 13, 2008 3:02 am
by 15049124
I implemented the code in my application and boosted it.

The code below is the core of the functionality I'm looking for.

It works fairy well but really not as intended. For example:
1. MakingIsoAxis don't produce any effect if it is invoked in the same
procedure where the graphic is done. If you code it as an independent
event it does.
2. If you click several times the command1 button the graph is shrunk
each time. The drawing looks Isometric once the graph stops shrinking.
3. I've added a teecommand control to allow rotation and some other
settings. When you use the rotation tool, the graphic goes out of
out proportion.

Well, that's about Isometric axis.

The walls of the box are drawn using pont3D series. My real intention is
to draw them as solid walls. I can draw horizontal and tilted planes using
surface3D but how to draw vertical planes (xy and yz planes)

I hope you could help me.

Thanks a lot

QuijoteMx





Code: Select all

Option Explicit

Const pi = 3.14159265358979

Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long
       
Private Const HORZSIZE = 4
Private Const VERTSIZE = 6

Private Sub Command1_Click()
   MakeIsoAxis TChart1
End Sub

Private Sub Form_Load()
Dim x, z As Integer
 
  TeeCommander1.Chart = TChart1
  
  ScaleMode = vbPixels
 
  TChart1.Aspect.Chart3DPercent = 100
  TChart1.Legend.Visible = False
 
    drawThebox 50, 50, 25
End Sub


Private Sub MakeIsoAxis(AChart As TChart)
Dim tmpX, tmpY, tmpZ, XRange, YRange, ZRange, Offset, XYScreen As Double
  With AChart
    If (.ChartHeight > 0) And (.ChartWidth > 0) Then
      With .Axis.Bottom
        XRange = .Maximum - .Minimum
      End With
     
      With .Axis.Left
        YRange = .Maximum - .Minimum
      End With
     
     
      With .Axis.Depth
        ZRange = .Maximum - .Minimum
      End With

      XYScreen = (GetDeviceCaps(.Canvas.HandleDC, HORZSIZE) / Screen.Width) / (GetDeviceCaps(.Canvas.HandleDC, VERTSIZE) / Screen.Height)

      tmpX = (XRange / .ChartWidth)
      tmpY = (YRange / .ChartHeight) * XYScreen
      tmpZ = (ZRange / (.Axis.Depth.IEndPos - .Axis.Depth.IStartPos)) * XYScreen / 2

      If tmpX > tmpY And tmpX > tmpZ Then
        If tmpY <> 0 Then
          Offset = ((YRange * tmpX / tmpY) - YRange) / 2

          With .Axis.Left
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If

        If tmpZ <> 0 Then
          Offset = ((ZRange * tmpX / tmpZ) - ZRange)

          With .Axis.Depth
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If
      Else
        If tmpY > tmpX And tmpY > tmpZ Then
          If tmpX <> 0 Then
            Offset = ((XRange * tmpY / tmpX) - XRange) / 2

            With .Axis.Bottom
              .SetMinMax .Minimum - Offset, .Maximum + Offset
            End With
          End If

          If tmpZ <> 0 Then
            Offset = ((ZRange * tmpY / tmpZ) - ZRange)

            With .Axis.Depth
              .SetMinMax .Minimum - Offset, .Maximum + Offset
            End With
          End If
        Else
          If tmpX <> 0 Then
            Offset = ((XRange * tmpZ / tmpX) - XRange) / 2

            With .Axis.Bottom
              .SetMinMax .Minimum - Offset, .Maximum + Offset
            End With
          End If

          If tmpY <> 0 Then
            Offset = ((YRange * tmpZ / tmpY) - YRange) / 2

            With .Axis.Left
              .SetMinMax .Minimum - Offset, .Maximum + Offset
            End With
          End If
        End If
      End If
    End If
  End With
End Sub

Private Sub addPoint3DSeries(theChart As TChart, lastSeriesPointer As Integer, Optional visiblePointer = False, Optional PenWidth = 2)
   With theChart
        .AddSeries (scPoint3D)
        lastSeriesPointer = .SeriesCount - 1
        .Series(lastSeriesPointer).asPoint3D.Pointer.Visible = False
        .Series(lastSeriesPointer).Pen.Width = 2
    End With
End Sub


Private Sub drawThebox(Largo, Ancho, Alto)
    Dim newSeries As Integer
    Dim btapa As Single
    
'---
'   bTapa=ancho de la hoja que forma la tapa
'---
    btapa = Ancho / 2
    With TChart1
               
'--- Plano Largo-Alto (0). Cara larga del frente
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, 0, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor

'--- Plano Largo-Alto (0). Tapa del frente
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto - Cos(45 * pi / 180) * btapa, -btapa, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto - Cos(45 * pi / 180) * btapa, -btapa, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor

'--- Plano Largo-Alto (1). Cara larga del fondo
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, 0, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, Ancho, "", clTeeColor

'--- Plano Largo-Alto (1). Tapa del fondo
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto + btapa, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto + btapa, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor

'--- Plano Ancho-Alto (0). Cara izquierda
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, 0, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, 0, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor

'--- Plano Ancho-Alto (0). Tapa de la izquierda
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto + btapa, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto + btapa, Ancho, "", clTeeColor

'--- Plano Ancho-Alto (1). Cara derecha
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor

'--- Plano Ancho-Alto (1). Tapa derecha
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo + Cos(45 * pi / 180) * btapa, Alto - Cos(45 * pi / 180) * btapa, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo + Cos(45 * pi / 180) * btapa, Alto - Cos(45 * pi / 180) * btapa, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor
    End With
End Sub


Any hint?

Posted: Thu Jun 19, 2008 12:29 pm
by 15049124
i'm really :(

Posted: Fri Jun 20, 2008 8:36 am
by yeray
Hi QuijoteMX,

Excuse us for the delay. We haven't forgotten you. I made some tests and found some problems. So, as soon as we'll find the solution we'll tell you. Please, be patient.

3D ISOMETRIC AXIS

Posted: Fri Jun 20, 2008 12:40 pm
by 15049124
Thank you!. I didn't want to be rude. I apologize if I look alike.

QuijoteMX

Posted: Fri Jun 20, 2008 1:17 pm
by yeray
Hi QuijoteMX,

Could you test the following code and see if it's what you are looking for?
We think that the rotation problem is now solved but if you find any problem, please feel free to tell us.

Code: Select all

Option Explicit

Const pi = 3.14159265358979

Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long

Private Const HORZSIZE = 4
Private Const VERTSIZE = 6

Private Sub Command1_Click()
   MakeIsoAxis TChart1
End Sub

Private Sub Form_Load()
Dim X, z As Integer
  TeeCommander1.Chart = TChart1

  ScaleMode = vbPixels

  TChart1.Aspect.Zoom = 70
  TChart1.Aspect.Orthogonal = False
  TChart1.Aspect.Chart3DPercent = 100
  TChart1.Legend.Visible = False
  
  TChart1.Axis.Left.Increment = 5
  TChart1.Axis.Bottom.Increment = 5
  TChart1.Axis.Depth.Visible = True
  TChart1.Axis.Depth.Increment = 5

  TChart1.AddSeries scPoint3D

  For X = 1 To 49
    For z = 1 To 49
      TChart1.Series(0).asPoint3D.AddXYZ X, Rnd * 24, z, "", clTeeColor
    Next z
  Next X

  TChart1.Series(0).asPoint3D.AddXYZ 1, 49, 1, "", clTeeColor
  TChart1.Series(0).SetNull TChart1.Series(0).Count - 1  'point added to redimension to show the whole box

  TChart1.Environment.InternalRepaint
  drawThebox 50, 50, 25
  MakeIsoAxis TChart1
End Sub

Private Sub MakeIsoAxis(AChart As TChart)
Dim tmpX, tmpY, tmpZ, XRange, YRange, ZRange, Offset, XYScreen As Double
  With AChart
    .Axis.Bottom.Automatic = False
    .Axis.Left.Automatic = False
    .Axis.Depth.Automatic = False

    If (.ChartHeight > 0) And (.ChartWidth > 0) Then
      With .Axis.Bottom
        XRange = .Maximum - .Minimum
      End With

      With .Axis.Left
        YRange = .Maximum - .Minimum
      End With


      With .Axis.Depth
        ZRange = .Maximum - .Minimum
      End With

      XYScreen = (GetDeviceCaps(.Canvas.HandleDC, HORZSIZE) / Screen.Width) / (GetDeviceCaps(.Canvas.HandleDC, VERTSIZE) / Screen.Height)

      tmpX = (XRange / .ChartWidth)
      tmpY = (YRange / .ChartHeight) * XYScreen
      tmpZ = (ZRange / (.Axis.Depth.IEndPos - .Axis.Depth.IStartPos)) * XYScreen

      If tmpX > tmpY And tmpX > tmpZ Then
        If tmpY <> 0 Then
          Offset = ((YRange * tmpX / tmpY) - YRange) / 2

          With .Axis.Left
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If

        If tmpZ <> 0 Then
          Offset = ((ZRange * tmpX / tmpZ) - ZRange) / 2

          With .Axis.Depth
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If
      End If

      If tmpY > tmpX And tmpY > tmpZ Then
        If tmpX <> 0 Then
          Offset = ((XRange * tmpY / tmpX) - XRange) / 2

          With .Axis.Bottom
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If

        If tmpZ <> 0 Then
          Offset = ((ZRange * tmpY / tmpZ) - ZRange) / 2

          With .Axis.Depth
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If
      End If

      If tmpZ > tmpX And tmpZ > tmpY Then
        If tmpX <> 0 Then
          Offset = ((XRange * tmpZ / tmpX) - XRange) / 2

          With .Axis.Bottom
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If

        If tmpY <> 0 Then
          Offset = ((YRange * tmpZ / tmpY) - YRange) / 2

          With .Axis.Left
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If
      End If
    End If
  End With
End Sub

Private Sub addPoint3DSeries(theChart As TChart, lastSeriesPointer As Integer, Optional visiblePointer = False, Optional PenWidth = 2)
   With theChart
        .AddSeries (scPoint3D)
        lastSeriesPointer = .SeriesCount - 1
        .Series(lastSeriesPointer).asPoint3D.Pointer.Visible = False
        .Series(lastSeriesPointer).Pen.Width = 2
    End With
End Sub


Private Sub drawThebox(Largo, Ancho, Alto)
    Dim newSeries As Integer
    Dim btapa As Single

'---
'   bTapa=ancho de la hoja que forma la tapa
'---
    btapa = Ancho / 2
    With TChart1

'--- Plano Largo-Alto (0). Cara larga del frente
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, 0, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor

'--- Plano Largo-Alto (0). Tapa del frente
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto - Cos(45 * pi / 180) * btapa, -btapa, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto - Cos(45 * pi / 180) * btapa, -btapa, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor

'--- Plano Largo-Alto (1). Cara larga del fondo
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, 0, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, Ancho, "", clTeeColor

'--- Plano Largo-Alto (1). Tapa del fondo
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto + btapa, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto + btapa, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor

'--- Plano Ancho-Alto (0). Cara izquierda
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, 0, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, 0, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor

'--- Plano Ancho-Alto (0). Tapa de la izquierda
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto + btapa, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto + btapa, Ancho, "", clTeeColor

'--- Plano Ancho-Alto (1). Cara derecha
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor

'--- Plano Ancho-Alto (1). Tapa derecha
            addPoint3DSeries TChart1, newSeries
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo + Cos(45 * pi / 180) * btapa, Alto - Cos(45 * pi / 180) * btapa, 0, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo + Cos(45 * pi / 180) * btapa, Alto - Cos(45 * pi / 180) * btapa, Ancho, "", clTeeColor
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor
    End With
End Sub
And regarding the problem of painting the walls of the box. Here there is an example of how you could paint two planes. You shouldn't find problems in implementing the others:

Code: Select all

Private Sub TChart1_OnAfterDraw()
  If TChart1.SeriesCount = 9 Then
    With TChart1
      .Canvas.Brush.Color = vbWhite
      .Canvas.Brush.Style = bsSolid
      .Canvas.BackMode = cbmOpaque
    
      .Canvas.PlaneFour3D .Series(1).CalcXPos(3), .Series(1).CalcYPos(3), _
                          .Series(1).CalcXPos(0), .Series(1).CalcYPos(0), _
                          .Series(1).CalcXPos(1), .Series(1).CalcYPos(1), _
                          .Series(1).CalcXPos(2), .Series(1).CalcYPos(2), _
                          .Series(1).asPoint3D.CalcZPos(3), .Series(1).asPoint3D.CalcZPos(3)

      .Canvas.Plane3D .Series(1).CalcXPos(3), .Series(1).CalcYPos(3), _
                      .Series(2).CalcXPos(2), .Series(2).CalcYPos(2), _
                      .Series(1).asPoint3D.CalcZPos(3), .Series(2).asPoint3D.CalcZPos(2)
    End With
  End If
End Sub

I'm stuck

Posted: Tue Jul 15, 2008 4:22 am
by 15049124
Hi Narcis!

I made a first down, but I'm still in yard number 20.

The code I've added implements your recommendations. But I'm far away of the functionality I'm looking for.

I've drawn all the surfaces of the box using 3dpoint series and looks fine but I don't get the oblique planes to look opaque.

could you help me ...

Thank you in advance ...

QuixioteMx

Code: Select all

Option Explicit

Const pi = 3.14159265358979

Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long

Private Const HORZSIZE = 4
Private Const VERTSIZE = 6

Dim Largo, Ancho, Alto
Dim RADS



Private Sub Form_Load()
  TeeCommander1.Chart = TChart2
'  ChartGrid1.Chart = TChart2

  ScaleMode = vbPixels
  aNGLE = 45
  drawBox3d
End Sub

Private Sub makeIsoAxisBis(AChart As TChart)
Dim tmpX, tmpY, tmpZ, XRange, YRange, ZRange, Offset, XYScreen As Double
  On Error Resume Next
  With AChart
    .Axis.Bottom.Automatic = False
    .Axis.Left.Automatic = False
    .Axis.Depth.Automatic = False

    If (.ChartHeight > 0) And (.ChartWidth > 0) Then
      With .Axis.Bottom
        XRange = .Maximum - .Minimum
      End With

      With .Axis.Left
        YRange = .Maximum - .Minimum
      End With


      With .Axis.Depth
        ZRange = .Maximum - .Minimum
      End With

      XYScreen = (GetDeviceCaps(.Canvas.HandleDC, HORZSIZE) / Screen.Width) / (GetDeviceCaps(.Canvas.HandleDC, VERTSIZE) / Screen.Height)

      tmpX = (XRange / .ChartWidth)
      tmpY = (YRange / .ChartHeight) * XYScreen
      tmpZ = (ZRange / (.Axis.Depth.IEndPos - .Axis.Depth.IStartPos)) * XYScreen

      If tmpX > tmpY And tmpX > tmpZ Then
        If tmpY <> 0 Then
          Offset = ((YRange * tmpX / tmpY) - YRange) / 2

          With .Axis.Left
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If

        If tmpZ <> 0 Then
          Offset = ((ZRange * tmpX / tmpZ) - ZRange) / 2

          With .Axis.Depth
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If
      End If

      If tmpY > tmpX And tmpY > tmpZ Then
        If tmpX <> 0 Then
          Offset = ((XRange * tmpY / tmpX) - XRange) / 2

          With .Axis.Bottom
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If

        If tmpZ <> 0 Then
          Offset = ((ZRange * tmpY / tmpZ) - ZRange) / 2

          With .Axis.Depth
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If
      End If

      If tmpZ > tmpX And tmpZ > tmpY Then
        If tmpX <> 0 Then
          Offset = ((XRange * tmpZ / tmpX) - XRange) / 2

          With .Axis.Bottom
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If

        If tmpY <> 0 Then
          Offset = ((YRange * tmpZ / tmpY) - YRange) / 2

          With .Axis.Left
            .SetMinMax .Minimum - Offset, .Maximum + Offset
          End With
        End If
      End If
    End If
  End With
  On Error GoTo 0
End Sub

Private Sub addpoint3dSeriesBis(theChart As TChart, lastSeriesPointer As Integer, Optional visiblePointer = False, Optional PenWidth = 2)
   With theChart
        .AddSeries (scPoint3D)
        lastSeriesPointer = .SeriesCount - 1
        .Series(lastSeriesPointer).asPoint3D.Pointer.Visible = True
        .Series(lastSeriesPointer).Pen.Width = 2
    End With
End Sub
Private Sub drawBox3d()
  Dim newSeries As Integer
    
  Dim X, z As Integer
  
  TChart2.RemoveAllSeries
  
  TChart2.Aspect.Zoom = 30
  TChart2.Aspect.Orthogonal = False
  TChart2.Aspect.Chart3DPercent = 100
  TChart2.Legend.Visible = False
 
  TChart2.Axis.Left.Visible = True
  TChart2.Axis.Bottom.Visible = False
  TChart2.Axis.Depth.Visible = False
  TChart2.Walls.Visible = False
  
  TChart2.AddSeries scPoint3D

  Largo = 75
  Ancho = 50
  Alto = 25

  For X = 1 To Largo - 1
    For z = 1 To Ancho - 1
      TChart2.Series(0).asPoint3D.AddXYZ X, Rnd * (Alto + 0.5 * Ancho - 1), z, "", clTeeColor
    Next z
  Next X

  TChart2.Series(0).asPoint3D.AddXYZ 1, Ancho / 2 + Alto - 1, 1, "", clTeeColor
  TChart2.Series(0).SetNull TChart2.Series(0).Count - 1  'point added to redimension to show the whole box

  TChart2.Environment.InternalRepaint
  TChart2.Series(0).Active = False

    
    addpoint3dSeriesBis TChart2, newSeries 'Serie 1
    
    With TChart2
             RADS = Val(aNGLE) * pi / 180
            
            .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor 'Punto 0
            .Series(newSeries).asPoint3D.AddXYZ Largo, 0, 0, "", clTeeColor ' Punto 1
            .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "", clTeeColor ' Punto 2
            .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor ' Punto 3
            .Series(newSeries).asPoint3D.AddXYZ 0, 0, 0, "", clTeeColor ' punto 4
    
            .Series(newSeries).asPoint3D.AddXYZ 0, 0, Ancho, "", clTeeColor 'Punto 5
            .Series(newSeries).asPoint3D.AddXYZ Largo, 0, Ancho, "", clTeeColor ' Punto 6
            .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor ' Punto 7
            .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor ' Punto 8
            .Series(newSeries).asPoint3D.AddXYZ 0, 0, Ancho, "", clTeeColor ' Punto 9

            .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor ' punto 10
            .Series(newSeries).asPoint3D.AddXYZ 0, Alto + 0.5 * Ancho * Sin(RADS), Ancho + 0.5 * Ancho * Cos(RADS), "", clTeeColor ' punto 11
            .Series(newSeries).asPoint3D.AddXYZ Largo, Alto + 0.5 * Ancho * Sin(RADS), Ancho + 0.5 * Ancho * Cos(RADS), "", clTeeColor ' punto 12
           .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "", clTeeColor  ' punto 13
           
           .Series(newSeries).asPoint3D.AddXYZ 0, Alto, Ancho, "", clTeeColor  ' punto 14

            .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "", clTeeColor ' punto 14
            .Series(newSeries).asPoint3D.AddXYZ 0, Alto + 0.5 * Ancho, 0, "", clTeeColor ' punto 15
            .Series(newSeries).asPoint3D.AddXYZ 0, Alto + 0.5 * Ancho, Ancho, "", clTeeColor ' punto 16

            .Series(newSeries).asPoint3D.AddXYZ 0, Alto, 0, "17", clTeeColor  ' punto 17
            .Series(newSeries).asPoint3D.AddXYZ 0, Alto - 0.5 * Ancho * Sin(RADS), -0.5 * Ancho * Cos(RADS), "18", vbRed ' punto 18
            .Series(newSeries).asPoint3D.AddXYZ Largo, Alto - 0.5 * Ancho * Sin(RADS), -0.5 * Ancho * Cos(RADS), "19", clTeeColor ' punto 19
            .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, 0, "20", clTeeColor  ' punto 20

            .Series(newSeries).asPoint3D.AddXYZ Largo + 0.5 * Ancho * Cos(RADS), Alto - 0.5 * Ancho * Sin(RADS), 0, "21", clTeeColor ' punto 21
            .Series(newSeries).asPoint3D.AddXYZ Largo + 0.5 * Ancho * Cos(RADS), Alto - 0.5 * Ancho * Sin(RADS), Ancho, "22", clTeeColor ' punto 22
            .Series(newSeries).asPoint3D.AddXYZ Largo, Alto, Ancho, "23", clTeeColor   ' punto 23
            
    End With

  makeIsoAxisBis TChart2
  TChart2.Aspect.OpenGL.Active = True
'  TChart2.Series(1).Marks.Visible = True
'  TChart2.Series(1).Marks.Font.Size = 30

End Sub



Private Sub Slider1_Change()
    aNGLE = Slider1.Value
    drawBox3d
End Sub

Private Sub tchart2_OnAfterDraw()
  If TChart2.SeriesCount = 2 Then
    With TChart2
            .Canvas.Brush.Color = vbCyan
            .Canvas.Brush.Style = bsSolid
            .Canvas.BackMode = cbmOpaque
            
           .Canvas.PlaneFour3D .Series(1).CalcXPos(0), .Series(1).CalcYPos(0), _
                          .Series(1).CalcXPos(1), .Series(1).CalcYPos(1), _
                          .Series(1).CalcXPos(2), .Series(1).CalcYPos(2), _
                          .Series(1).CalcXPos(3), .Series(1).CalcYPos(3), _
                          .Series(1).asPoint3D.CalcZPos(3), .Series(1).asPoint3D.CalcZPos(3)
    
            .Canvas.RectangleWithZ .Series(1).CalcXPos(0), .Series(1).CalcYPos(1), .Series(1).CalcXPos(2), .Series(1).CalcYPos(3), .Series(1).asPoint3D.CalcZPos(0)
           .Canvas.RectangleWithZ .Series(1).CalcXPos(5), .Series(1).CalcYPos(6), .Series(1).CalcXPos(7), .Series(1).CalcYPos(8), .Series(1).asPoint3D.CalcZPos(5)
            .Canvas.RectangleY .Series(1).CalcXPos(0), .Series(1).CalcYPos(0), .Series(1).CalcXPos(2), .Series(1).asPoint3D.CalcZPos(0), .Series(1).asPoint3D.CalcZPos(5)
            .Canvas.Plane3D .Series(1).CalcXPos(0), .Series(1).CalcYPos(0), .Series(1).CalcXPos(8), .Series(1).CalcYPos(8), .Series(1).asPoint3D.CalcZPos(0), .Series(1).asPoint3D.CalcZPos(8)
            .Canvas.Plane3D .Series(1).CalcXPos(1), .Series(1).CalcYPos(1), .Series(1).CalcXPos(7), .Series(1).CalcYPos(7), .Series(1).asPoint3D.CalcZPos(1), .Series(1).asPoint3D.CalcZPos(7)

            .Canvas.RectangleWithZ .Series(1).CalcXPos(10), .Series(1).CalcYPos(11), .Series(1).CalcXPos(12), .Series(1).CalcYPos(13), .Series(1).asPoint3D.CalcZPos(10)
            .Canvas.Plane3D .Series(1).CalcXPos(14), .Series(1).CalcYPos(14), .Series(1).CalcXPos(16), .Series(1).CalcYPos(16), .Series(1).asPoint3D.CalcZPos(14), .Series(1).asPoint3D.CalcZPos(16)


            .Canvas.Plane3D .Series(1).CalcXPos(18), .Series(1).CalcYPos(18), .Series(1).CalcXPos(20), .Series(1).CalcYPos(20), .Series(1).asPoint3D.CalcZPos(18), .Series(1).asPoint3D.CalcZPos(20)

    End With
  End If
End Sub



Private Sub tchart2_OnClickSeries(ByVal SeriesIndex As Long, ByVal ValueIndex As Long, ByVal Button As TeeChart.EMouseButton, ByVal Shift As TeeChart.EShiftState, ByVal X As Long, ByVal Y As Long)
    TChart2.StopMouse
End Sub

Posted: Tue Jul 15, 2008 9:22 am
by yeray
Hi QuixioteMx,

Here is how I would draw the first two planes. Note that now the point series is not needed but I calculate the points in the same way.

Code: Select all

Private Sub TChart1_OnAfterDraw()
Dim Ancho, Largo, Alto, InicioX, InicioY, InicioZ, FinX, FinY, FinZ, btapa
  
  Ancho = 50
  Largo = 50
  Alto = 25
  btapa = Ancho / 2
  
  With TChart1.Canvas
    .Brush.Color = vbWhite
    .Brush.Style = bsSolid
    .BackMode = cbmOpaque
  End With
  
  '--- Plano Largo-Alto (0). Cara larga del frente
  With TChart1.Axis
    InicioX = .Bottom.CalcXPosValue(0)
    InicioY = .Left.CalcYPosValue(0)
    InicioZ = .Depth.CalcPosPoint(0)
  
    FinX = .Bottom.CalcXPosValue(Largo)
    FinY = .Left.CalcYPosValue(Alto)
    FinZ = .Depth.CalcPosPoint(Ancho)
  End With
  
  With TChart1.Canvas
    .PlaneFour3D InicioX, InicioY, _
          InicioX, FinY, _
          FinX, FinY, _
          FinX, InicioY, _
          InicioZ, FinZ
  End With
  
  '--- Plano Largo-Alto (0). Tapa del frente
  With TChart1.Axis
    InicioX = .Bottom.CalcXPosValue(0)
    InicioY = .Left.CalcYPosValue(Alto)
    InicioZ = .Depth.CalcPosPoint(0)
  
    FinX = .Bottom.CalcXPosValue(Largo)
    FinY = .Left.CalcYPosValue(Alto - Cos(45 * pi / 180) * btapa)
    FinZ = .Depth.CalcXPosValue(-btapa)
  End With
  
  With TChart1.Canvas
    .PlaneFour3D InicioX, InicioY, _
          FinX, InicioY, _
          FinX, FinY, _
          InicioX, FinY, _
          InicioZ, FinZ
  End With
End Sub