123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-"
- """
- Euler-Bricks - 2020 - by psy (epsylon@riseup.net)
- You should have received a copy of the GNU General Public License along
- with Euler-Bricks; if not, write to the Free Software Foundation, Inc., 51
- Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- """
- import os, sys, math
- import numpy as np
- from mpl_toolkits.mplot3d import Axes3D
- from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
- import matplotlib.pyplot as plt
- plt.rcParams.update({'figure.max_open_warning': 0})
- class EulerBrick(object):
- def __init__(self):
- self.store_bricks = "bricks/"
- def banner(self):
- print(75*"=")
- print(" _____ _ ____ _ _ ")
- print(" | ____| _| | ___ _ __| __ ) _ __(_) ___| | _____ ")
- print(" | _|| | | | |/ _ \ '__| _ \| '__| |/ __| |/ / __| ")
- print(" | |__| |_| | | __/ | | |_) | | | | (__| <\__ \ ")
- print(" |_____\__,_|_|\___|_| |____/|_| |_|\___|_|\_\___/ ")
- print(" ")
- print(75*"=","\n")
- print(" Does a 'perfect cuboid' exist?\n")
- print(75*"=","\n")
- def run(self, opts=None):
- self.banner()
- self.mode=input(" -Set mode: manual (default), learning (M/l): ")
- self.root=input(" -Set range (ex: 1-1000 or 1000-1000000 (PRESS ENTER = 1-1000) (STOP = CTRL+z): ")
- if not self.root:
- self.root="1-1000"
- print("\n[Info] Looking for 'bricks' in the range: "+ str(self.root)+ "\n")
- self.generate_bricks(self.root)
- def generate_bricks(self, rng):
- srng = rng.split('-')
- try:
- minrange=int(srng[0])
- maxrange=int(srng[1])
- except:
- print(40*"-"+"\n")
- print("[Error] Numbers on range should be integers (ex: 1-1000). Aborting...\n")
- sys.exit(2)
- if minrange < maxrange:
- pass
- else:
- print(40*"-"+"\n")
- print("[Error] Min range should be minor than max range (ex: 1-1000). Aborting...\n")
- sys.exit(2)
- self.init = int(minrange)
- self.end = int(maxrange)
- n = 1
- if not os.path.exists(self.store_bricks):
- os.mkdir(self.store_bricks)
- for a in range(self.init, self.end):
- asq = a**2
- for b in range(a, self.end):
- bsq = b**2
- d = math.sqrt(asq + bsq)
- if not d.is_integer():
- continue
- for c in range(b, self.end):
- n = n + 1
- csq = c**2
- e = math.sqrt(asq + csq)
- if not e.is_integer():
- continue
- f = math.sqrt(bsq + csq)
- if not f.is_integer():
- continue
- print(40*"-"+"\n")
- print("[Info] Found 'brick'!!\n")
- print(" -ID: {} ({})".format(n, str(c)+':'+str(b)+':'+str(a)))
- print(" -Hedges: X={} Y={} Z={}".format(int(c), int(b), int(a)))
- print(" -Diagonals: dZY={} dXZ={} dXY={}".format(int(d), int(e), int(f)))
- self.draw(a,b,c,d,e,f,n)
- def draw(self, a, b, c, d, e, f, n):
- points = np.array([[c, b, a],
- [c, -b, -a],
- [c, b, -a ],
- [-c, b, -a],
- [-c, -b, a],
- [c, -b, a ],
- [c, b, a ],
- [-c, b, a]])
- P = [[2.06498904e-01 , -6.30755443e-07 , 1.07477548e-03],
- [1.61535574e-06 , 1.18897198e-01 , 7.85307721e-06],
- [7.08353661e-02 , 4.48415767e-06 , 2.05395893e-01]]
- Z = np.zeros((8,3))
- for i in range(8): Z[i,:] = np.dot(points[i,:],P)
- Z = 1*Z
- fig = plt.figure()
- ax = fig.add_subplot(111, projection='3d')
- r = [-1,1]
- X, Y = np.meshgrid(r, r)
- ax.scatter3D(Z[:, 0], Z[:, 1], Z[:, 2])
- verts = [[Z[0],Z[1],Z[2],Z[3]],
- [Z[4],Z[5],Z[6],Z[7]],
- [Z[0],Z[1],Z[5],Z[4]],
- [Z[2],Z[3],Z[7],Z[6]],
- [Z[1],Z[2],Z[6],Z[5]],
- [Z[4],Z[7],Z[3],Z[0]]]
- verts2 = [[-Z[0],-Z[1],-Z[2],-Z[3]],
- [-Z[4],-Z[5],-Z[6],-Z[7]],
- [-Z[0],-Z[1],-Z[5],-Z[4]],
- [-Z[2],-Z[3],-Z[7],-Z[6]],
- [-Z[1],-Z[2],-Z[6],-Z[5]],
- [-Z[4],-Z[7],-Z[3],-Z[0]]]
- ax.add_collection3d(Poly3DCollection(verts, facecolors='cyan', linewidths=1, edgecolors='r', alpha=.25))
- ax.add_collection3d(Poly3DCollection(verts2, facecolors='cyan', linewidths=0, edgecolors='r', alpha=.25))
- ax.set_xlabel("X: {} dXY: {} dXZ: {}".format(int(c),int(f),int(e)))
- ax.set_ylabel("Y: {} dYX: {} dYZ: {}".format(int(b),int(f),int(d)))
- ax.set_zlabel("Z: {} dZX: {} dZY: {}".format(int(a),int(e),int(d)))
- ax.w_xaxis.set_ticklabels("")
- ax.w_yaxis.set_ticklabels("")
- ax.w_zaxis.set_ticklabels("")
- header = "[{}".format("x:"+str(c)+' y:'+str(b)+' z:'+str(a) + "]\n")
- fig.canvas.set_window_title("Euler's brick ID: {} ".format(n))
- plt.title(header)
- if not os.path.exists(self.store_bricks+str(a)+'_'+str(b)+'_'+str(c)+"-euler_brick.png"):
- fig.savefig(self.store_bricks+str(c)+'_'+str(b)+'_'+str(a)+"-euler_brick.png")
- print("\n[Info] Generated 'brick' image at: "+self.store_bricks+str(c)+'_'+str(b)+'_'+str(a)+"-euler_brick.png\n")
- else:
- print("\n[Info] You have previously saved this 'brick'...\n")
- if not self.mode == "l" or self.mode == "L" or self.mode == "Learn" or self.mode == "learn":
- plt.show()
- ax.clear()
- if __name__ == "__main__":
- app = EulerBrick()
- app.run()
|