Click here to Skip to main content
15,896,359 members
Articles / Desktop Programming / WPF

WPF: Rubik's Cube

Rate me:
Please Sign up or sign in to vote.
4.97/5 (112 votes)
24 Sep 2014CPOL3 min read 174.9K   10.2K   154  
A WPF 3D Rubik's Cube application
Imports System.Windows.Media.Media3D
Imports System.Windows.Media.Animation

Public Class CubePiece
    Public piece As ModelVisual3D

    Private axisPoint As New Point3D(0, 0, 0)
    Private axisAngleRtn3D As New AxisAngleRotation3D(New Vector3D(0, 0, 1), 0)
    Private dblAnimation As DoubleAnimation
    Private rotateTx3D As RotateTransform3D
    Private tx3dGroup As New Transform3DGroup

    Private Const ROTATION_TIME As Double = 200
    Friend Property PieceLocation() As PieceLocations

    Private Sub RotateAroundAxis(ByVal angle As Double)
        rotateTx3D = New RotateTransform3D(axisAngleRtn3D, axisPoint)
        dblAnimation = New DoubleAnimation(CDbl(angle), TimeSpan.FromMilliseconds(ROTATION_TIME), FillBehavior.HoldEnd)
        axisAngleRtn3D.BeginAnimation(AxisAngleRotation3D.AngleProperty, dblAnimation)
        tx3dGroup.Children.Add(rotateTx3D)
        piece.Transform = tx3dGroup
    End Sub

    ''' <summary>
    ''' Rotate cube piece around the X-axis
    ''' </summary>
    ''' <param name="angle">The angle of rotation; -90° or 90°</param>
    Public Sub RotateAround_X_axis(ByVal angle As Double)
        axisAngleRtn3D = New AxisAngleRotation3D(New Vector3D(1, 0, 0), 0)
        RotateAroundAxis(angle)
        ChangeLocationOnXaxisRotation(angle)
    End Sub

    ''' <summary>
    ''' Rotate cube piece around the Y-axis
    ''' </summary>
    ''' <param name="angle">The angle of rotation; -90° or 90°</param>
    Public Sub RotateAround_Y_axis(ByVal angle As Double)
        axisAngleRtn3D = New AxisAngleRotation3D(New Vector3D(0, 1, 0), 0)
        RotateAroundAxis(angle)
        ChangeLocationOnYaxisRotation(angle)
    End Sub

    ''' <summary>
    ''' Rotate cube piece around the Z-axis
    ''' </summary>
    ''' <param name="angle">The angle of rotation; -90° or 90°</param>
    Public Sub RotateAround_Z_axis(ByVal angle As Double)
        axisAngleRtn3D = New AxisAngleRotation3D(New Vector3D(0, 0, 1), 0)
        RotateAroundAxis(angle)
        ChangeLocationOnZaxisRotation(angle)
    End Sub

    Private Sub ChangeLocationOnXaxisRotation(ByVal angle As Double)
        ' Looking from R-to-L. 
        ' 90° (anti-clockwise rotation)
        If (angle > 0) Then
            Select Case PieceLocation
                ' First layer.
                Case PieceLocations.FUR
                    PieceLocation = PieceLocations.FDR
                Case PieceLocations.RU
                    PieceLocation = PieceLocations.FR
                Case PieceLocations.BUR
                    PieceLocation = PieceLocations.FUR
                Case PieceLocations.BR
                    PieceLocation = PieceLocations.RU
                Case PieceLocations.BDR
                    PieceLocation = PieceLocations.BUR
                Case PieceLocations.RD
                    PieceLocation = PieceLocations.BR
                Case PieceLocations.FDR
                    PieceLocation = PieceLocations.BDR
                Case PieceLocations.FR
                    PieceLocation = PieceLocations.RD
                    ' Second layer.
                Case PieceLocations.FU
                    PieceLocation = PieceLocations.FD
                Case PieceLocations.UC
                    PieceLocation = PieceLocations.FC
                Case PieceLocations.BU
                    PieceLocation = PieceLocations.FU
                Case PieceLocations.BC
                    PieceLocation = PieceLocations.UC
                Case PieceLocations.BD
                    PieceLocation = PieceLocations.BU
                Case PieceLocations.DC
                    PieceLocation = PieceLocations.BC
                Case PieceLocations.FD
                    PieceLocation = PieceLocations.BD
                Case PieceLocations.FC
                    PieceLocation = PieceLocations.DC
                    ' Third layer.
                Case PieceLocations.FUL
                    PieceLocation = PieceLocations.FDL
                Case PieceLocations.LU
                    PieceLocation = PieceLocations.FL
                Case PieceLocations.BUL
                    PieceLocation = PieceLocations.FUL
                Case PieceLocations.BL
                    PieceLocation = PieceLocations.LU
                Case PieceLocations.BDL
                    PieceLocation = PieceLocations.BUL
                Case PieceLocations.LD
                    PieceLocation = PieceLocations.BL
                Case PieceLocations.FDL
                    PieceLocation = PieceLocations.BDL
                Case PieceLocations.FL
                    PieceLocation = PieceLocations.LD
            End Select
        Else
            ' -90° (clockwise rotation)
            Select Case PieceLocation
                ' First layer.
                Case PieceLocations.FUR
                    PieceLocation = PieceLocations.BUR
                Case PieceLocations.RU
                    PieceLocation = PieceLocations.BR
                Case PieceLocations.BUR
                    PieceLocation = PieceLocations.BDR
                Case PieceLocations.BR
                    PieceLocation = PieceLocations.RD
                Case PieceLocations.BDR
                    PieceLocation = PieceLocations.FDR
                Case PieceLocations.RD
                    PieceLocation = PieceLocations.FR
                Case PieceLocations.FDR
                    PieceLocation = PieceLocations.FUR
                Case PieceLocations.FR
                    PieceLocation = PieceLocations.RU
                    ' Second layer.
                Case PieceLocations.FU
                    PieceLocation = PieceLocations.BU
                Case PieceLocations.UC
                    PieceLocation = PieceLocations.BC
                Case PieceLocations.BU
                    PieceLocation = PieceLocations.BD
                Case PieceLocations.BC
                    PieceLocation = PieceLocations.DC
                Case PieceLocations.BD
                    PieceLocation = PieceLocations.FD
                Case PieceLocations.DC
                    PieceLocation = PieceLocations.FC
                Case PieceLocations.FD
                    PieceLocation = PieceLocations.FU
                Case PieceLocations.FC
                    PieceLocation = PieceLocations.UC
                    ' Third layer.
                Case PieceLocations.FUL
                    PieceLocation = PieceLocations.BUL
                Case PieceLocations.LU
                    PieceLocation = PieceLocations.BL
                Case PieceLocations.BUL
                    PieceLocation = PieceLocations.BDL
                Case PieceLocations.BL
                    PieceLocation = PieceLocations.LD
                Case PieceLocations.BDL
                    PieceLocation = PieceLocations.FDL
                Case PieceLocations.LD
                    PieceLocation = PieceLocations.FL
                Case PieceLocations.FDL
                    PieceLocation = PieceLocations.FUL
                Case PieceLocations.FL
                    PieceLocation = PieceLocations.LU
            End Select
        End If
    End Sub

    Private Sub ChangeLocationOnYaxisRotation(ByVal angle As Double)
        ' Looking from U-to-D.
        ' 90° (anti-clockwise rotation)
        If angle > 0 Then
            Select Case PieceLocation
                ' First layer.
                Case PieceLocations.FUL
                    PieceLocation = PieceLocations.FUR
                Case PieceLocations.FU
                    PieceLocation = PieceLocations.RU
                Case PieceLocations.FUR
                    PieceLocation = PieceLocations.BUR
                Case PieceLocations.RU
                    PieceLocation = PieceLocations.BU
                Case PieceLocations.BUR
                    PieceLocation = PieceLocations.BUL
                Case PieceLocations.BU
                    PieceLocation = PieceLocations.LU
                Case PieceLocations.BUL
                    PieceLocation = PieceLocations.FUL
                Case PieceLocations.LU
                    PieceLocation = PieceLocations.FU
                    ' Second layer.
                Case PieceLocations.FL
                    PieceLocation = PieceLocations.FR
                Case PieceLocations.FC
                    PieceLocation = PieceLocations.RC
                Case PieceLocations.FR
                    PieceLocation = PieceLocations.BR
                Case PieceLocations.RC
                    PieceLocation = PieceLocations.BC
                Case PieceLocations.BR
                    PieceLocation = PieceLocations.BL
                Case PieceLocations.BC
                    PieceLocation = PieceLocations.LC
                Case PieceLocations.BL
                    PieceLocation = PieceLocations.FL
                Case PieceLocations.LC
                    PieceLocation = PieceLocations.FC
                    ' Third layer.
                Case PieceLocations.FDL
                    PieceLocation = PieceLocations.FDR
                Case PieceLocations.FD
                    PieceLocation = PieceLocations.RD
                Case PieceLocations.FDR
                    PieceLocation = PieceLocations.BDR
                Case PieceLocations.RD
                    PieceLocation = PieceLocations.BD
                Case PieceLocations.BDR
                    PieceLocation = PieceLocations.BDL
                Case PieceLocations.BD
                    PieceLocation = PieceLocations.LD
                Case PieceLocations.BDL
                    PieceLocation = PieceLocations.FDL
                Case PieceLocations.LD
                    PieceLocation = PieceLocations.FD
            End Select
        Else
            ' -90° (clockwise rotation)
            Select Case PieceLocation
                ' First layer.
                Case PieceLocations.FUL
                    PieceLocation = PieceLocations.BUL
                Case PieceLocations.FU
                    PieceLocation = PieceLocations.LU
                Case PieceLocations.FUR
                    PieceLocation = PieceLocations.FUL
                Case PieceLocations.RU
                    PieceLocation = PieceLocations.FU
                Case PieceLocations.BUR
                    PieceLocation = PieceLocations.FUR
                Case PieceLocations.BU
                    PieceLocation = PieceLocations.RU
                Case PieceLocations.BUL
                    PieceLocation = PieceLocations.BUR
                Case PieceLocations.LU
                    PieceLocation = PieceLocations.BU
                    ' Second layer.
                Case PieceLocations.FL
                    PieceLocation = PieceLocations.BL
                Case PieceLocations.FC
                    PieceLocation = PieceLocations.LC
                Case PieceLocations.FR
                    PieceLocation = PieceLocations.FL
                Case PieceLocations.RC
                    PieceLocation = PieceLocations.FC
                Case PieceLocations.BR
                    PieceLocation = PieceLocations.FR
                Case PieceLocations.BC
                    PieceLocation = PieceLocations.RC
                Case PieceLocations.BL
                    PieceLocation = PieceLocations.BR
                Case PieceLocations.LC
                    PieceLocation = PieceLocations.BC
                    ' Third layer.
                Case PieceLocations.FDL
                    PieceLocation = PieceLocations.BDL
                Case PieceLocations.FD
                    PieceLocation = PieceLocations.LD
                Case PieceLocations.FDR
                    PieceLocation = PieceLocations.FDL
                Case PieceLocations.RD
                    PieceLocation = PieceLocations.FD
                Case PieceLocations.BDR
                    PieceLocation = PieceLocations.FDR
                Case PieceLocations.BD
                    PieceLocation = PieceLocations.RD
                Case PieceLocations.BDL
                    PieceLocation = PieceLocations.BDR
                Case PieceLocations.LD
                    PieceLocation = PieceLocations.BD
            End Select
        End If
    End Sub

    Private Sub ChangeLocationOnZaxisRotation(ByVal angle As Double)
        ' Looking from F-to-B.
        ' 90° (anti-clockwise rotation)
        If (angle > 0) Then
            Select Case PieceLocation
                ' First layer.
                Case PieceLocations.FUL
                    PieceLocation = PieceLocations.FDL
                Case PieceLocations.FU
                    PieceLocation = PieceLocations.FL
                Case PieceLocations.FUR
                    PieceLocation = PieceLocations.FUL
                Case PieceLocations.FR
                    PieceLocation = PieceLocations.FU
                Case PieceLocations.FDR
                    PieceLocation = PieceLocations.FUR
                Case PieceLocations.FD
                    PieceLocation = PieceLocations.FR
                Case PieceLocations.FDL
                    PieceLocation = PieceLocations.FDR
                Case PieceLocations.FL
                    PieceLocation = PieceLocations.FD
                    ' Second layer.
                Case PieceLocations.LU
                    PieceLocation = PieceLocations.LD
                Case PieceLocations.UC
                    PieceLocation = PieceLocations.LC
                Case PieceLocations.RU
                    PieceLocation = PieceLocations.LU
                Case PieceLocations.RC
                    PieceLocation = PieceLocations.UC
                Case PieceLocations.RD
                    PieceLocation = PieceLocations.RU
                Case PieceLocations.DC
                    PieceLocation = PieceLocations.RC
                Case PieceLocations.LD
                    PieceLocation = PieceLocations.RD
                Case PieceLocations.LC
                    PieceLocation = PieceLocations.DC
                    ' Third layer.
                Case PieceLocations.BUL
                    PieceLocation = PieceLocations.BDL
                Case PieceLocations.BU
                    PieceLocation = PieceLocations.BL
                Case PieceLocations.BUR
                    PieceLocation = PieceLocations.BUL
                Case PieceLocations.BR
                    PieceLocation = PieceLocations.BU
                Case PieceLocations.BDR
                    PieceLocation = PieceLocations.BUR
                Case PieceLocations.BD
                    PieceLocation = PieceLocations.BR
                Case PieceLocations.BDL
                    PieceLocation = PieceLocations.BDR
                Case PieceLocations.BL
                    PieceLocation = PieceLocations.BD
            End Select
        Else
            ' -90° angle (clockwise rotation).
            Select Case PieceLocation
                ' First layer.
                Case PieceLocations.FUL
                    PieceLocation = PieceLocations.FUR
                Case PieceLocations.FU
                    PieceLocation = PieceLocations.FR
                Case PieceLocations.FUR
                    PieceLocation = PieceLocations.FDR
                Case PieceLocations.FR
                    PieceLocation = PieceLocations.FD
                Case PieceLocations.FDR
                    PieceLocation = PieceLocations.FDL
                Case PieceLocations.FD
                    PieceLocation = PieceLocations.FL
                Case PieceLocations.FDL
                    PieceLocation = PieceLocations.FUL
                Case PieceLocations.FL
                    PieceLocation = PieceLocations.FU
                    ' Second layer.
                Case PieceLocations.LU
                    PieceLocation = PieceLocations.RU
                Case PieceLocations.UC
                    PieceLocation = PieceLocations.RC
                Case PieceLocations.RU
                    PieceLocation = PieceLocations.RD
                Case PieceLocations.RC
                    PieceLocation = PieceLocations.DC
                Case PieceLocations.RD
                    PieceLocation = PieceLocations.LD
                Case PieceLocations.DC
                    PieceLocation = PieceLocations.LC
                Case PieceLocations.LD
                    PieceLocation = PieceLocations.LU
                Case PieceLocations.LC
                    PieceLocation = PieceLocations.UC
                    ' Third layer.
                Case PieceLocations.BUL
                    PieceLocation = PieceLocations.BUR
                Case PieceLocations.BU
                    PieceLocation = PieceLocations.BR
                Case PieceLocations.BUR
                    PieceLocation = PieceLocations.BDR
                Case PieceLocations.BR
                    PieceLocation = PieceLocations.BD
                Case PieceLocations.BDR
                    PieceLocation = PieceLocations.BDL
                Case PieceLocations.BD
                    PieceLocation = PieceLocations.BL
                Case PieceLocations.BDL
                    PieceLocation = PieceLocations.BUL
                Case PieceLocations.BL
                    PieceLocation = PieceLocations.BU
            End Select
        End If
    End Sub
End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Kenya Kenya
Experienced C# software developer with a passion for WPF.

Awards,
  • CodeProject MVP 2013
  • CodeProject MVP 2012
  • CodeProject MVP 2021

Comments and Discussions