October 22, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Create a 3D Cube Structure for GDI+

  • September 15, 2004
  • By Paul Kimmel
  • Send Email »
  • More Articles »

Implementing Behaviors

At this point, the bulk of the remaining work is the implementation of constructors and methods for calculating the points needed to describe the sides of a cube. For the most part, I used the constructors to initialize fields, and the side-drawing code is very similar for each of the sides. The most difficult part is the meticulous arithmetic necessary to ensure that all of the edges match. Listing 3 contains the remaining code (including the code already provided) for the Cube structure.

Listing 3: The complete Cube structure listing

Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D

Public Enum RotateHorizontal
    Left = -1
    Center = 0
    Right = 1
End Enum

Public Enum RotateVertical
    Up = -1
    Center = 0
    Down = 1
End Enum

Public Enum CubeSides
    Left
    Right
    Top
    Bottom
    Front
    Back
End Enum


Public Structure Cube
    Private FLocation As Point
    Private FHeight As Integer
    Private FWidth As Integer
    Private FDepth As Integer
    Private FCenter As Point
    Private FPath As GraphicsPath
    Private FRotateX As RotateHorizontal
    Private FRotateY As RotateVertical

    Public Property Location() As Point
        Get
            Return FLocation
        End Get
        Set(ByVal Value As Point)
            FLocation = Value
            Changed()
        End Set
    End Property

    Public Property Height() As Integer
        Get
            Return FHeight
        End Get
        Set(ByVal Value As Integer)
            FHeight = Value
            Changed()
        End Set
    End Property

    Public Property Width() As Integer
        Get
            Return FWidth
        End Get
        Set(ByVal Value As Integer)
            FWidth = Value
            Changed()
        End Set
    End Property

    Public Property Depth() As Integer
        Get
            Return FDepth
        End Get
        Set(ByVal Value As Integer)
            FDepth = Value
            Changed()
        End Set
    End Property

    Public Property Center() As Point
        Get
            Return FCenter
        End Get
        Set(ByVal Value As Point)
            FCenter = Value
            Changed()
        End Set
    End Property

    Public ReadOnly Property Path() As GraphicsPath
        Get
            Return FPath
        End Get
    End Property

    Public Property RotateX() As RotateHorizontal
        Get
            Return FRotateX
        End Get
        Set(ByVal Value As RotateHorizontal)
            FRotateX = Value
            Changed()
        End Set
    End Property

    Public Property RotateY() As RotateVertical
        Get
            Return FRotateY
        End Get
        Set(ByVal Value As RotateVertical)
            FRotateY = Value
            Changed()
        End Set
    End Property

    Public ReadOnly Property X() As Integer
        Get
            Return FLocation.X
        End Get
    End Property

    Public ReadOnly Property Y() As Integer
        Get
            Return FLocation.Y
        End Get
    End Property

    'Return the rectangle that bounds the entire polygon
    'representing the cube
    Public ReadOnly Property BoundsRect() As Rectangle
        Get
            If (FPath Is Nothing) Then
                Return New Rectangle(0, 0, 0, 0)
            Else
                Dim r As RectangleF = Path.GetBounds()
                ' Implicit conversion from single to integer,
                ' really only available in VB
                Return New Rectangle(r.X, r.Y, r.Width, r.Height)
            End If
        End Get
    End Property

    Public Property Size() As CubeSize
        Get
            Return New CubeSize(FWidth, FHeight, FDepth)
        End Get
        Set(ByVal Value As CubeSize)
            FWidth = Value.Width
            FHeight = Value.Height
            FDepth = Value.Depth
            Changed()
        End Set
    End Property

    Public ReadOnly Property Item(ByVal index As CubeSides) -
           As Point()
        Get
            Select Case index
                Case CubeSides.Back
                    Return Back
                Case CubeSides.Front
                    Return Front
                Case CubeSides.Left
                    Return Left
                Case CubeSides.Right
                    Return Right
                Case CubeSides.Top
                    Return Top
                Case CubeSides.Bottom
                    Return Bottom
                Case Else
                    Return Front
            End Select
        End Get
    End Property

    Public ReadOnly Property Top() As Point()
        Get
            Return GetTop(Location, Height, Width, Depth, _
                          RotateX, RotateY)
        End Get
    End Property

    Public ReadOnly Property Bottom() As Point()
        Get
            Return GetBottom(Location, Height, Width, Depth, _
                             RotateX, RotateY)
        End Get
    End Property

    Public ReadOnly Property Left() As Point()
        Get
            Return GetLeft(Location, Height, Width, Depth, _
                           RotateX, RotateY)
        End Get
    End Property

    Public ReadOnly Property Right() As Point()
        Get
            Return GetRight(Location, Height, Width, Depth, _
                            RotateX, RotateY)
        End Get
    End Property

    Public ReadOnly Property Front() As Point()
        Get
            Return GetFront(Location, Height, Width, Depth, _
                            RotateX, RotateY)
        End Get
    End Property

    Public ReadOnly Property Back() As Point()
        Get
            Return GetBack(Location, Height, Width, Depth, _
                           RotateX, RotateY)
        End Get
    End Property

    Public Sub New(ByVal x As Integer, ByVal Y As Integer, _
        ByVal height As Integer, ByVal width As Integer, _
        ByVal depth As Integer, ByVal rotateX As RotateHorizontal, _
        ByVal rotateY As RotateVertical)

        FPath = New GraphicsPath
        FLocation = New Point(x, Y)
        FHeight = height
        FWidth = width
        FDepth = depth
        FRotateX = rotateX
        FRotateY = rotateY
        FCenter = New Point(Location.X + (width + depth / 2 * _
                                          rotateX) / 2, _
            Location.Y + (height + depth / 2 * rotateY) / 2)

        ConstructPath()

    End Sub

    Public Sub New(ByVal x As Integer, ByVal Y As Integer, _
            ByVal height As Integer, ByVal width As Integer, _
            ByVal depth As Integer)

        FPath = New GraphicsPath
        FLocation = New Point(x, Y)
        FHeight = height
        FWidth = width
        FDepth = depth
        FRotateX = RotateHorizontal.Right
        FRotateY = RotateVertical.Up
        FCenter = New Point(Location.X + (width + depth / 2 * _
                                          rotateX) / 2, _
            Location.Y + (height + depth / 2 * rotateY) / 2)

        ConstructPath()

    End Sub

    Public Sub New(ByVal point As Point, _
        ByVal height As Integer, ByVal width As Integer, _
        ByVal depth As Integer)

        FPath = New GraphicsPath
        FLocation = point
        FHeight = Height
        FWidth = Width
        FDepth = Depth
        FRotateX = RotateHorizontal.Right
        FRotateY = RotateVertical.Up
        FCenter = New Point(Location.X + (Width + Depth / 2 * _
                                          RotateX) / 2, _
            Location.Y + (Height + Depth / 2 * RotateY) / 2)

        ConstructPath()

    End Sub

    Public Sub New(ByVal point As Point, ByVal size As CubeSize)

        FPath = New GraphicsPath
        FLocation = point
        FHeight = size.Height
        FWidth = size.Width
        FDepth = size.Depth
        FRotateX = RotateHorizontal.Right
        FRotateY = RotateVertical.Up
        FCenter = New Point(Location.X + (width + depth / 2 * _
                            RotateX) / 2, _
            Location.Y + (height + depth / 2 * RotateY) / 2)

        ConstructPath()

    End Sub

    Private Sub Changed()
        ConstructPath()
    End Sub

    Private Sub ConstructPath()
        FPath = New GraphicsPath
        Path.AddLines(GetBack(Location, Height, Width, Depth, _
                      RotateX, RotateY))
        Path.AddLines(GetFront(Location, Height, Width, Depth, _
                      RotateX, RotateY))
        Path.AddLines(GetTop(Location, Height, Width, Depth, _
                      RotateX, RotateY))
        Path.AddLines(GetBottom(Location, Height, Width, Depth, _
                      RotateX, RotateY))
        Path.AddLines(GetLeft(Location, Height, Width, Depth, _
                      RotateX, RotateY))
        Path.AddLines(GetRight(Location, Height, Width, Depth, _
                      RotateX, RotateY))
    End Sub

    Private Function GetXFromCenter(ByVal newCenter As Point) _
            As Integer
        Return newCenter.X - (FWidth + FDepth / 2 * FRotateX) / 2
    End Function

    Private Function GetYFromCenter(ByVal newCenter As Point) _
            As Integer
        Return newCenter.Y - (FHeight + FDepth / 2 * FRotateY) / 2
    End Function

    Public Sub FilleRectangle(ByVal boundingRect As Rectangle)
        Dim x As Integer
        If (FRotateX = RotateHorizontal.Right) Then
            x = 0
        Else
            x = Math.Abs(Depth / 2 * FRotateX)
        End If

        Dim y As Integer
        If (FRotateY = RotateVertical.Down) Then
            y = 0
        Else
            y = Math.Abs(Depth / 2 * RotateY)
        End If

        FLocation = New Point(x, y)
        FWidth = boundingRect.Width - Depth / 2 - 1
        FHeight = boundingRect.Height - Depth / 2 - 1
        ConstructPath()
    End Sub

    Public Function GetCube() As GraphicsPath
        Return FPath
    End Function

    Public Function GetSides(ByVal theseSides As CubeSides()) _
           As GraphicsPath
        Dim newPath As GraphicsPath = New GraphicsPath
        Dim I As Integer
        For I = 0 To theseSides.Length - 1
            newPath.AddLines(Item(theseSides(I)))
        Next I

        Return newPath
    End Function

    Public Shared Function GetXOffset(ByVal depth As Integer, _
        ByVal rotateX As RotateHorizontal) As Integer

        Return depth / 2 * rotateX
    End Function

    Public Shared Function GetYOffset(ByVal depth As Integer, _
        ByVal rotateY As RotateVertical) As Integer

        Return depth / 2 * rotateY
    End Function

    Public Shared Function GetTop(ByVal point As Point, _
                                  ByVal height As Integer, _
                                  ByVal width As Integer, _
                                  ByVal depth As Integer, _
                                  ByVal rotateX As RotateHorizontal, _
                                  ByVal rotateY As RotateVertical) _
                                        As Point()

        Return New Point() { _
            New Point(point.X, point.Y), _
New Point(point.X + GetXOffset(depth, rotateX), point.Y + _
GetYOffset(depth, rotateY)), _
            New Point(point.X + width + GetXOffset(depth, rotateX), _
point.Y + GetYOffset(depth, rotateY)), _
            New Point(point.X + width, point.Y), _
            New Point(point.X, point.Y)}
    End Function

    Public Shared Function GetLeft(ByVal point As Point, _
           ByVal height As Integer, _
    ByVal width As Integer, ByVal depth As Integer, _
          ByVal rotateX As RotateHorizontal, _
    ByVal rotateY As RotateVertical)

        Return New Point() {New Point(point.X, point.Y), _
            New Point(point.X + GetXOffset(depth, rotateX), _
                point.Y + GetYOffset(depth, rotateY)), _
            New Point(point.X + GetXOffset(depth, rotateX), _
                point.Y + GetYOffset(depth, rotateY) + height), _
            New Point(point.X, point.Y + height), _
            New Point(point.X, point.Y)}
    End Function

    Public Shared Function GetRight(ByVal point As Point, _
           ByVal height As Integer, _
        ByVal width As Integer, ByVal depth As Integer, _
        ByVal rotateX As RotateHorizontal, ByVal rotateY _
              As RotateVertical)

        Return New Point() {New Point(point.X + width, point.Y), _
            New Point(point.X + width + GetXOffset(depth, rotateX), _
                      point.Y + GetYOffset(depth, rotateY)), _
            New Point(point.X + width + GetXOffset(depth, rotateX), _
                      point.Y + GetYOffset(depth, rotateY) + height), _
            New Point(point.X + width, point.Y + height), _
            New Point(point.X + width, point.Y)}
    End Function

    Public Shared Function GetBottom(ByVal point As Point, _
           ByVal height As Integer, _
           ByVal width As Integer, ByVal depth As Integer, _
           ByVal rotateX As RotateHorizontal, _
           ByVal rotateY As RotateVertical) As Point()


        Return New Point() {New Point(point.X, point.Y + height), _
            New Point(point.X + GetXOffset(depth, rotateX), _
                point.Y + GetYOffset(depth, rotateY) + height), _
            New Point(point.X + width + GetXOffset(depth, rotateX), _
                point.Y + GetYOffset(depth, rotateY) + height), _
            New Point(point.X + width, point.Y + height), _
            New Point(point.X, point.Y + height)}
    End Function

    Public Shared Function GetFront(ByVal point As Point, _
           ByVal height As Integer, _
           ByVal width As Integer, ByVal depth As Integer, _
           ByVal rotateX As RotateHorizontal, ByVal rotateY _
           As RotateVertical) As Point()

        Return New Point() {point, New Point(point.X + width, point.Y), _
            New Point(point.X + width, point.Y + height), _
            New Point(point.X, point.Y + height), point}

    End Function

    Public Shared Function GetBack(ByVal point As Point, _
           ByVal height As Integer, _
           ByVal width As Integer, ByVal depth As Integer, _
           ByVal rotateX As RotateHorizontal, _
           ByVal rotateY As RotateVertical) As Point()

        Dim topLeft As Point = New Point(point.X + _
            GetXOffset(depth, rotateX), _
            point.Y + GetYOffset(depth, rotateY))

        Dim topRight As Point = New Point(point.X + width + _
            GetXOffset(depth, rotateX), point.Y + _
            GetYOffset(depth, rotateY))

        Dim bottomRight As Point = New Point(point.X + width + _
            GetXOffset(depth, rotateX), point.Y + height + _
            GetYOffset(depth, rotateY))

        Dim bottomLeft As Point = New Point(point.X + _
            GetXOffset(depth, rotateX), point.Y + height + _
            GetYOffset(depth, rotateY))

        Return New Point() {topLeft, topRight, bottomRight, _
                            bottomLeft, topLeft}

    End Function

End Structure




Page 2 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel