Advertisement
LaMarmotte

Penrose Staircase in Excel

Nov 28th, 2014
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 'Generates a Penrose staircase in Excel using Anik Soulière's tool for visualisation in R3
  2. 'Link to download the file :
  3. 'https://www.dropbox.com/s/yg52g3kgxhpisrq/Algeb_ConcoursObjet_3D_EscalierPenrose_avecScript.xlsm?dl=0
  4. 'Sorry it's in French honhonhon
  5.  
  6. Private Type point
  7.     x As Single
  8.     y As Single
  9.     z As Single
  10.    
  11. End Type
  12.    
  13. Private Enum escalier1
  14.     'CONSTANTES ATTRIBUABLES AUX MARCHES
  15.    '"nbre_" correspondant au nombre de marches (_ = côté)
  16.    nbre1 = 5
  17.     nbre2 = 5
  18.     nbre3 = 3
  19.     nbre4 = 1
  20.     nbre5 = 0
  21.     nbre7 = 2
  22.     nbre8 = 4
  23.     'Lignes et colonnes initiales
  24.    Linit = 9
  25.     Cinit = 28
  26.  
  27. End Enum
  28.  
  29.  
  30. Sub Main()
  31.     'INITIALISATIONS
  32.    Dim cePoint As point, precPoint As point
  33.     Dim hauteur As Single, giron As Single
  34.         hauteur = 0.2
  35.         giron = 2
  36.     Dim nbreMarches As New Collection
  37.         nbreMarches.Add 5
  38.         nbreMarches.Add 5
  39.         nbreMarches.Add 4
  40.         nbreMarches.Add 1
  41.         nbreMarches.Add 0
  42.         nbreMarches.Add 0
  43.         nbreMarches.Add 3
  44.         nbreMarches.Add 4
  45.         nbreMarches.Add 5
  46.     Dim cellPres As Range
  47.     Dim compteur As Integer
  48.         compteur = 0
  49.     Dim priorite As Boolean
  50.         priorite = 0
  51.     Dim Ccour As Integer
  52.         Ccour = Cinit
  53.  
  54.     Dim orientation As Integer
  55.         orientation = 1
  56.     'Base
  57.    Set cellPres = Cells(Linit, 16)
  58.     cePoint.x = 6
  59.     cePoint.y = 6
  60.     cePoint.z = 0
  61.     precPoint = cePoint
  62.    
  63.     Call base(cePoint, cellPres, giron, hauteur, nbreMarches)
  64.    
  65.     cePoint.z = cePoint.z + hauteur * 3
  66.     Call imprPoint(cePoint, cellPres)
  67.     Set cellPres = Cells(Linit, cellPres.Column + 1)
  68.    
  69.     Ccour = cellPres.Column
  70.     'Marches
  71.    For orientation = 1 To 9
  72.        
  73.         Select Case orientation
  74.             Case 1
  75.                 Set cellPres = Cells(Linit, Ccour)
  76.                 limite = nbreMarches.Item(orientation)
  77.                 priorite = 0
  78.             Case 2
  79.                 Set cellPres = Cells(Linit, Ccour)
  80.                 limite = nbreMarches.Item(orientation)
  81.                 priorite = 0
  82.             Case 3
  83.                 Set cellPres = Cells(Linit, Ccour)
  84.                 limite = nbreMarches.Item(orientation)
  85.                 priorite = 0
  86.                 'Ccour = Ccour - 1
  87.            Case 4
  88.                 Set cellPres = Cells(Linit, Ccour)
  89.                 limite = nbreMarches.Item(orientation)
  90.                 priorite = 0
  91.                 Ccour = Ccour - 1
  92.             Case 5
  93.                 Set cellPres = Cells(Linit, Ccour)
  94.                 limite = nbreMarches.Item(orientation)
  95.                 Ccour = Ccour - 1
  96.             Case 6
  97.                 Set cellPres = Cells(Linit, Ccour)
  98.                 limite = nbreMarches.Item(orientation)
  99.             Case 7
  100.                 Set cellPres = Cells(Linit, Ccour)
  101.                 limite = nbreMarches.Item(orientation)
  102.                 priorite = True
  103.             Case 8
  104.                 Set cellPres = Cells(Linit, Ccour)
  105.                 limite = nbreMarches.Item(orientation)
  106.                 priorite = True
  107.             Case 9
  108.                 Set cellPres = Cells(Linit, Ccour)
  109.                 limite = nbreMarches.Item(orientation)
  110.                 priorite = True
  111.         End Select
  112.  
  113.         precPoint.x = Cells(cellPres.Row, cellPres.Column - 1).Value
  114.         precPoint.y = Cells(cellPres.Row + 1, cellPres.Column - 1).Value
  115.         precPoint.z = Cells(cellPres.Row + 2, cellPres.Column - 1).Value
  116.        
  117.        
  118.         For compteur = 0 To limite Step 1
  119.             If priorite = 0 Then
  120.                 'Donne longueur à la marche
  121.                cePoint = avancerPoint(precPoint, giron, orientation)
  122.                 Call imprPoint(cePoint, cellPres)
  123.                 precPoint = cePoint
  124.                 Set cellPres = Cells(cellPres.Row, cellPres.Column + 1)
  125.                 Ccour = Ccour + 1
  126.                 Call barreTransversale(cePoint, cellPres, orientation, Ccour, giron)
  127.             priorite = 1
  128.             End If
  129.             If priorite = True Then
  130.                 If orientation = 1 Or orientation = 2 Or orientation = 3 Or orientation = 4 Then
  131.                     If compteur = limite Then Exit For
  132.                 ElseIf orientation = 9 Then
  133.                     If compteur = limite Then
  134.                         hauteur = 3 * hauteur
  135.                         Call barreTransversale(cePoint, cellPres, 3, Ccour, giron)
  136.                     End If
  137.                 End If
  138.                
  139.                'Monte vers porchaine marche
  140.                cePoint = monterPoint(precPoint, hauteur, orientation)
  141.                 Call imprPoint(cePoint, cellPres)
  142.                 precPoint = cePoint
  143.                 Set cellPres = Cells(cellPres.Row, cellPres.Column + 1)
  144.                 Ccour = Ccour + 1
  145.                 Call barreTransversale(cePoint, cellPres, orientation, Ccour, giron)
  146.                 priorite = 0
  147.             End If
  148.         Next compteur
  149.         compteur = 0
  150.     Next orientation
  151.    
  152.  
  153.    
  154.    
  155.    
  156. End Sub
  157.  
  158. Function avancerPoint(precPoint As point, ByVal giron As Single, ByVal orientation As Integer) As point
  159.     avancerPoint.x = precPoint.x
  160.     avancerPoint.y = precPoint.y
  161.     avancerPoint.z = precPoint.z
  162.     Select Case orientation
  163.         Case 1, 5, 7
  164.             avancerPoint.y = precPoint.y - giron
  165.         Case 2, 6
  166.             avancerPoint.x = precPoint.x - giron
  167.         Case 3, 9
  168.             avancerPoint.y = precPoint.y + giron
  169.         Case 4, 8
  170.             avancerPoint.x = precPoint.x + giron
  171.     End Select
  172.    
  173. End Function
  174.  
  175.  
  176. Function monterPoint(precPoint As point, ByVal hauteur As Single, ByVal orientation As Integer, Optional toutPlus As Boolean = False) As point
  177.     monterPoint.x = precPoint.x
  178.     monterPoint.y = precPoint.y
  179.     monterPoint.z = precPoint.z
  180.     Select Case orientation
  181.         Case 1, 2, 3, 4
  182.             monterPoint.z = precPoint.z + hauteur
  183.         Case 5
  184.             monterPoint.z = IIf(toutPlus, precPoint.z + hauteur, precPoint.z)
  185.         Case 6, 7, 8, 9
  186.             monterPoint.z = IIf(toutPlus, precPoint.z + hauteur, precPoint.z - hauteur)
  187.     End Select
  188.    
  189. End Function
  190.  
  191. Sub barreTransversale(point As point, cellu As Range, orientation As Integer, ByRef Ccour As Integer, giron As Single)
  192.     Dim pointTrans As point
  193.     pointTrans.x = point.x
  194.     pointTrans.y = point.y
  195.     pointTrans.z = point.z
  196.     Select Case orientation
  197.         Case 1
  198.             pointTrans.x = pointTrans.x - giron
  199.         Case 2
  200.             pointTrans.y = pointTrans.y + giron
  201.         Case 3
  202.             pointTrans.x = pointTrans.x + giron
  203.         Case 4
  204.             pointTrans.y = pointTrans.y - giron
  205.     End Select
  206.     'If orientation <= 4 Then
  207.    Call imprPoint(pointTrans, cellu)
  208.     Set cellu = Cells(cellu.Row, cellu.Column + 1)
  209.     Ccour = Ccour + 1
  210.     Call imprPoint(point, cellu)
  211.     Set cellu = Cells(cellu.Row, cellu.Column + 1)
  212.     Ccour = Ccour + 1
  213.     'End If
  214.            
  215. End Sub
  216.  
  217. 'Affecte les valeurs d'un point aux cellules correspondantes
  218. Sub imprPoint(point As point, cellu As Range)
  219.     Dim coo As Single
  220.     For i = 0 To 2
  221.         Select Case i
  222.             Case 0
  223.                 coo = point.x
  224.             Case 1
  225.                 coo = point.y
  226.             Case 2
  227.                 coo = point.z
  228.         End Select
  229.         Cells(cellu.Row + i, cellu.Column).Value = coo
  230.     Next i
  231.  
  232. End Sub
  233.  
  234. Sub base(cePoint As point, cellPres As Range, giron As Single, hauteur As Single, nbreMarches As Collection)
  235.     Dim pointInit As point
  236.     Dim pointInit2 As point
  237.     pointInit = cePoint
  238.     Dim nMarchesParc As Integer
  239.         nMarchesParc = 0
  240.    
  241.     Call imprPoint(cePoint, cellPres)
  242.     Set cellPres = Cells(Linit, cellPres.Column + 1)
  243.     For i = 1 To 9
  244.         For j = 0 To nbreMarches(i) - IIf(i < 7, 0, 1)
  245.             cePoint = avancerPoint(cePoint, giron, i)
  246.             nMarchesParc = IIf(i < 7, nMarchesParc + 1, nMarchesParc - 1)
  247.         Next j
  248.         Call imprPoint(cePoint, cellPres)
  249.         Set cellPres = Cells(Linit, cellPres.Column + 1)
  250.         pointInit2 = cePoint
  251.         cePoint.z = cePoint.z + hauteur * 3
  252.         For j = 2 To nMarchesParc
  253.             cePoint = monterPoint(cePoint, hauteur, i, IIf(i < 5, False, True))
  254.         Next j
  255.         Call imprPoint(cePoint, cellPres)
  256.         Set cellPres = Cells(Linit, cellPres.Column + 1)
  257.         cePoint = pointInit2
  258.         Call imprPoint(cePoint, cellPres)
  259.         Set cellPres = Cells(Linit, cellPres.Column + 1)
  260.         nMarchesParc = nMarchesParc - 1
  261.     Next i
  262.  
  263.     cePoint = pointInit
  264.     Call imprPoint(cePoint, cellPres)
  265.     Set cellPres = Cells(Linit, cellPres.Column + 1)
  266.  
  267. End Sub
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement