main.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-"
  3. """
  4. Euler-Bricks - 2020 - by psy (epsylon@riseup.net)
  5. You should have received a copy of the GNU General Public License along
  6. with Euler-Bricks; if not, write to the Free Software Foundation, Inc., 51
  7. Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  8. """
  9. import os, sys, math
  10. import numpy as np
  11. from mpl_toolkits.mplot3d import Axes3D
  12. from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
  13. import matplotlib.pyplot as plt
  14. plt.rcParams.update({'figure.max_open_warning': 0})
  15. class EulerBrick(object):
  16. def __init__(self):
  17. self.store_bricks = "bricks/"
  18. def banner(self):
  19. print(75*"=")
  20. print(" _____ _ ____ _ _ ")
  21. print(" | ____| _| | ___ _ __| __ ) _ __(_) ___| | _____ ")
  22. print(" | _|| | | | |/ _ \ '__| _ \| '__| |/ __| |/ / __| ")
  23. print(" | |__| |_| | | __/ | | |_) | | | | (__| <\__ \ ")
  24. print(" |_____\__,_|_|\___|_| |____/|_| |_|\___|_|\_\___/ ")
  25. print(" ")
  26. print(75*"=","\n")
  27. print(" Does a 'perfect cuboid' exist?\n")
  28. print(75*"=","\n")
  29. def run(self, opts=None):
  30. self.banner()
  31. self.mode=input(" -Set mode: manual (default), learning (M/l): ")
  32. self.root=input(" -Set range (ex: 1-1000 or 1000-1000000 (PRESS ENTER = 1-1000) (STOP = CTRL+z): ")
  33. if not self.root:
  34. self.root="1-1000"
  35. print("\n[Info] Looking for 'bricks' in the range: "+ str(self.root)+ "\n")
  36. self.generate_bricks(self.root)
  37. def generate_bricks(self, rng):
  38. srng = rng.split('-')
  39. try:
  40. minrange=int(srng[0])
  41. maxrange=int(srng[1])
  42. except:
  43. print(40*"-"+"\n")
  44. print("[Error] Numbers on range should be integers (ex: 1-1000). Aborting...\n")
  45. sys.exit(2)
  46. if minrange < maxrange:
  47. pass
  48. else:
  49. print(40*"-"+"\n")
  50. print("[Error] Min range should be minor than max range (ex: 1-1000). Aborting...\n")
  51. sys.exit(2)
  52. self.init = int(minrange)
  53. self.end = int(maxrange)
  54. n = 1
  55. if not os.path.exists(self.store_bricks):
  56. os.mkdir(self.store_bricks)
  57. for a in range(self.init, self.end):
  58. asq = a**2
  59. for b in range(a, self.end):
  60. bsq = b**2
  61. d = math.sqrt(asq + bsq)
  62. if not d.is_integer():
  63. continue
  64. for c in range(b, self.end):
  65. n = n + 1
  66. csq = c**2
  67. e = math.sqrt(asq + csq)
  68. if not e.is_integer():
  69. continue
  70. f = math.sqrt(bsq + csq)
  71. if not f.is_integer():
  72. continue
  73. print(40*"-"+"\n")
  74. print("[Info] Found 'brick'!!\n")
  75. print(" -ID: {} ({})".format(n, str(c)+':'+str(b)+':'+str(a)))
  76. print(" -Hedges: X={} Y={} Z={}".format(int(c), int(b), int(a)))
  77. print(" -Diagonals: dZY={} dXZ={} dXY={}".format(int(d), int(e), int(f)))
  78. self.draw(a,b,c,d,e,f,n)
  79. def draw(self, a, b, c, d, e, f, n):
  80. points = np.array([[c, b, a],
  81. [c, -b, -a],
  82. [c, b, -a ],
  83. [-c, b, -a],
  84. [-c, -b, a],
  85. [c, -b, a ],
  86. [c, b, a ],
  87. [-c, b, a]])
  88. P = [[2.06498904e-01 , -6.30755443e-07 , 1.07477548e-03],
  89. [1.61535574e-06 , 1.18897198e-01 , 7.85307721e-06],
  90. [7.08353661e-02 , 4.48415767e-06 , 2.05395893e-01]]
  91. Z = np.zeros((8,3))
  92. for i in range(8): Z[i,:] = np.dot(points[i,:],P)
  93. Z = 1*Z
  94. fig = plt.figure()
  95. ax = fig.add_subplot(111, projection='3d')
  96. r = [-1,1]
  97. X, Y = np.meshgrid(r, r)
  98. ax.scatter3D(Z[:, 0], Z[:, 1], Z[:, 2])
  99. verts = [[Z[0],Z[1],Z[2],Z[3]],
  100. [Z[4],Z[5],Z[6],Z[7]],
  101. [Z[0],Z[1],Z[5],Z[4]],
  102. [Z[2],Z[3],Z[7],Z[6]],
  103. [Z[1],Z[2],Z[6],Z[5]],
  104. [Z[4],Z[7],Z[3],Z[0]]]
  105. verts2 = [[-Z[0],-Z[1],-Z[2],-Z[3]],
  106. [-Z[4],-Z[5],-Z[6],-Z[7]],
  107. [-Z[0],-Z[1],-Z[5],-Z[4]],
  108. [-Z[2],-Z[3],-Z[7],-Z[6]],
  109. [-Z[1],-Z[2],-Z[6],-Z[5]],
  110. [-Z[4],-Z[7],-Z[3],-Z[0]]]
  111. ax.add_collection3d(Poly3DCollection(verts, facecolors='cyan', linewidths=1, edgecolors='r', alpha=.25))
  112. ax.add_collection3d(Poly3DCollection(verts2, facecolors='cyan', linewidths=0, edgecolors='r', alpha=.25))
  113. ax.set_xlabel("X: {} dXY: {} dXZ: {}".format(int(c),int(f),int(e)))
  114. ax.set_ylabel("Y: {} dYX: {} dYZ: {}".format(int(b),int(f),int(d)))
  115. ax.set_zlabel("Z: {} dZX: {} dZY: {}".format(int(a),int(e),int(d)))
  116. ax.w_xaxis.set_ticklabels("")
  117. ax.w_yaxis.set_ticklabels("")
  118. ax.w_zaxis.set_ticklabels("")
  119. header = "[{}".format("x:"+str(c)+' y:'+str(b)+' z:'+str(a) + "]\n")
  120. fig.canvas.set_window_title("Euler's brick ID: {} ".format(n))
  121. plt.title(header)
  122. if not os.path.exists(self.store_bricks+str(a)+'_'+str(b)+'_'+str(c)+"-euler_brick.png"):
  123. fig.savefig(self.store_bricks+str(c)+'_'+str(b)+'_'+str(a)+"-euler_brick.png")
  124. print("\n[Info] Generated 'brick' image at: "+self.store_bricks+str(c)+'_'+str(b)+'_'+str(a)+"-euler_brick.png\n")
  125. else:
  126. print("\n[Info] You have previously saved this 'brick'...\n")
  127. if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
  128. plt.show()
  129. ax.clear()
  130. if __name__ == "__main__":
  131. app = EulerBrick()
  132. app.run()