Commit 6019c27e authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

added a sub for php script

parent caedcd37
#!/usr/bin/env python3
'''
/**
* @file escher_pattern.py
* @brief escher pattern generator
* @par <b>License</b>:
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
'''
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import numpy as np
from matplotlib.patches import Arc
from matplotlib.patches import Circle
from matplotlib.patches import Rectangle
from matplotlib.patches import Polygon
from matplotlib.patches import Wedge
import matplotlib as mpl
from matplotlib import collections
from matplotlib.path import Path
import copy
import math
'''
requirements:
- matplotlib, version 3.0.3
- BUG?: matplotlib, version 2.0.2 draws a little padding around which is not desired
install:
- sudo pip3 install matplotlib
- sudo apt install python3-tk
'''
class Escher_Pattern:
# units are mms but coordinates are in pt to compare with php script
MM2PT = 72.0/25.4
# init
def __init__(self,
filename = "pattern.pdf",
width = 270, # width in units
height = 210, # height in units
lpm = 50, # lines per meter
escher = 2.0, # curvature coefficient
rotate = 5, # degrees
units = 'mm',
):
self.filename = filename
self.width = int(width*self.MM2PT)
self.height = int(height*self.MM2PT)
self.lpm = lpm
self.escher = escher
self.angle = rotate
self.units = units
plt.autoscale(tight=True)
plt.axis('off')
plt.margins(0.0)
self.fig, self.ax = plt.subplots()
self.ax.get_xaxis().set_visible(False)
self.ax.get_yaxis().set_visible(False)
self.ax.set_aspect('equal')
self.ax.spines['top'].set_visible(False)
self.ax.spines['right'].set_visible(False)
self.ax.spines['left'].set_visible(False)
self.ax.spines['bottom'].set_visible(False)
self.ax.set_ylim([0,self.height])
self.ax.set_xlim([0,self.width])
print("init done")
# rotate clock-wise
def rotate(self,deg):
t_start = self.ax.transData
t = mpl.transforms.Affine2D().rotate_deg(-deg)
t_end = t_start + t
for x in self.ax.patches + self.ax.collections:
x.set_transform(t_end)
def test1(self):
side = int(500/self.lpm*self.MM2PT)
if (self.escher>0):
Size = side
qSize = Size/4
hSize = Size/2
a = self.escher*(math.sqrt(2)-1.0)
r = (a*a+1)/(2*a)*qSize
r2 = r*r
h = math.sqrt(r2-qSize*qSize)
dc = 2*qSize-h
halfAngle = math.degrees(math.atan(qSize/h))
center = dc+r
tpts = [
[center-hSize, center-hSize],
[center-Size+dc, center-qSize],
[center-dc, center+qSize],
[center-qSize, center+Size-dc],
[center+qSize, center+dc],
[center+Size-dc, center+qSize],
[center+dc, center-qSize],
[center+qSize, center-Size+dc],
[center-qSize, center-dc]
]
template = [
Rectangle( tpts[0], side, side, facecolor="k",linewidth=0,edgecolor="r"),
Wedge( tpts[1], r, 0-halfAngle, 0+halfAngle,facecolor="w",linewidth=0,edgecolor="r"),
Wedge( tpts[2], r, 180-halfAngle,180+halfAngle,facecolor="k",linewidth=0,edgecolor="r"),
Wedge( tpts[3], r, 270-halfAngle,270+halfAngle,facecolor="w",linewidth=0,edgecolor="r"),
Wedge( tpts[4], r, 90-halfAngle, 90+halfAngle,facecolor="k",linewidth=0,edgecolor="r"),
Wedge( tpts[5], r, 180-halfAngle,180+halfAngle,facecolor="w",linewidth=0,edgecolor="r"),
Wedge( tpts[6], r, 0-halfAngle, 0+halfAngle,facecolor="k",linewidth=0,edgecolor="r"),
Wedge( tpts[7], r, 90-halfAngle, 90+halfAngle,facecolor="w",linewidth=0,edgecolor="r"),
Wedge( tpts[8], r, 270-halfAngle,270+halfAngle,facecolor="k",linewidth=0,edgecolor="r")
]
else:
tpts = [
[0,0]
]
template = [
Rectangle(tpts[0],side,side,facecolor="k",linewidth=0,edgecolor="r")
]
abs_angle_rad = math.radians(abs(self.angle))
extra_w = int(self.height*math.tan(abs_angle_rad)/side+1)*side
extra_h = int(self.width*math.tan(abs_angle_rad)/side+1)*side
a = range(-extra_w,self.width+extra_w,side)
b = range(-extra_h,self.height+extra_h,side)
for x, y in [(x,y) for x in a for y in b]:
# both even or both odd
if (x+y)/side%2==0:
for k,v in enumerate(template):
vcp = copy.copy(v)
if (type(v)==Wedge):
vcp.set_center((tpts[k][0]+x,tpts[k][1]+y))
elif (type(v)==Rectangle):
vcp.set_xy((tpts[k][0]+x,tpts[k][1]+y))
self.ax.add_patch(vcp)
# now rotate
self.rotate(self.angle)
# test
def test(self):
x = [0, 100, 0]
y = [0, 0, 100]
self.ax.fill(x, y)
circ = Circle((0,0),0.01,color="red")
#circ.set_transform(t_end)
self.ax.add_patch(circ)
circ = Circle((100,0),1,color="red")
#circ.set_transform(t_end)
self.ax.add_patch(circ)
circ = Circle((0,100),1,color="red")
#circ.set_transform(t_end)
self.ax.add_patch(circ)
circ = Circle((50,50),1,color="red")
#circ.set_transform(t_end)
self.ax.add_patch(circ)
# save function
def save(self):
pp = PdfPages(self.filename)
self.fig.tight_layout()
#plt.show()
self.fig.savefig(pp,format='pdf',bbox_inches='tight',pad_inches=0)
pp.close()
if __name__ == "__main__":
#ep = Escher_Pattern("test.pdf", escher=2.0, lpm=50, rotate=10)
#http://192.168.0.137/escher/escher_pattern.php?PAGE_WIDTH=1524&PAGE_HEIGHT=3048&LPM=2.705449885575893&ROTATE=14.036243467
ep = Escher_Pattern("test.pdf", width= 1524, height= 3048, escher=2.0, lpm=2.705449885575893, rotate=14.036243467)
ep.test1()
ep.save()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment