added mandelbrot stuff, changed draw and fourier and added an effective interpolation program for fourier transform

This commit is contained in:
2019-10-02 18:10:36 +02:00
parent 9dd3de63d2
commit 0c71015e3c
22 changed files with 857 additions and 58 deletions
@@ -1,4 +1,4 @@
from mysurface import Surface
from mycontext import Surface
from mybody import Body
from myabstract import Form,Point,Vector
from mymotion import Motion
@@ -0,0 +1,36 @@
import numpy as np
import pylab
# elephant parameters
p1, p2, p3, p4 = (50 - 30j, 18 + 8j, 12 - 10j, -14 - 60j )
p5 = 40 + 20j # eyepiece
def fourier(t, C):
f = np.zeros(t.shape)
A, B = C.real, C.imag
for k in range(len(C)):
f = f + A[k]*np.cos(k*t) + B[k]*np.sin(k*t)
return f
def elephant(t, p1, p2, p3, p4, p5):
npar = 6
Cx = np.zeros((npar,), dtype='complex')
Cy = np.zeros((npar,), dtype='complex')
Cx[1] = p1.real*1j
Cx[2] = p2.real*1j
Cx[3] = p3.real
Cx[5] = p4.real
Cy[1] = p4.imag + p1.imag*1j
Cy[2] = p2.imag*1j
Cy[3] = p3.imag*1j
x = np.append(fourier(t,Cx), [-p5.imag])
y = np.append(fourier(t,Cy), [p5.imag])
return x,y
x, y = elephant(np.linspace(0,2*np.pi,1000), p1, p2, p3, p4, p5)
pylab.plot(y,-x,'.')
pylab.show()
+28 -7
View File
@@ -7,6 +7,7 @@ import pygame
import logging
import copy
import mycolors
import random
# Interface Anatomy
# - show(context) //an anatomy must be responsible for drawing itself
@@ -36,17 +37,22 @@ class Body(Material):
return Body(form,motion,moment)
def createFromAbsolute(form,motion=Motion(),moment=Motion(d=1)):
"""Create a body from an absolute form."""
"""Create a body from an absolute form using its motion and its angular moment."""
motion.position=Vector(*form.center)
form.points=(-motion.position).applyToPoints(form.points)
return Body(form,motion,moment)
def __init__(self,form,motion=Motion(d=2),moment=Motion(d=1)):
"""Create body using form and optional name."""
"""Create body using its anatomy, its motion and its angular moment.
#Attributes:
#self.form,self.motion,self.moment
#Properties:
#self.absolute"""
self.form=form
self.motion=motion
self.moment=moment
def __str__(self):
"""Return the string representation of the body."""
return "b("+str(self.form)+","+str(self.motion)+")"
@@ -105,11 +111,12 @@ class Body(Material):
class PhysicalBody(Body):
def __init__(self,form,motion=Motion(d=2),moment=Motion(d=1),mass=1):
"""Create body using form and optional name."""
self.form=form
self.motion=motion
self.moment=moment
super().__init__(form,motion,moment)
self.mass=mass
def __str__(self):
"""Return the string representation of a physical body."""
return "p"+super().__str__()
@@ -117,5 +124,19 @@ class PhysicalBody(Body):
if __name__=="__main__":
from mysurface import Surface
surface=Surface(fullscreen=True)
from mycontext import Context
context=Context(fullscreen=False)
ru=random.uniform
form1=Form.random(n=4)
motion1=Motion(Vector(0,0),Vector(ru(-1,1),ru(-1,1)),Vector(0,0))
moment1=Motion(Vector([0]),Vector([ru(-1,1)]),Vector([0]))
b1=Body(form1,motion1,moment1)
#b=Body.random()
while context.open:
context.check()
context.clear()
context.show()
context.control()
b1.show(context)
b1.update(0.1)
context.flip()
+28 -17
View File
@@ -7,6 +7,11 @@ import mycolors
class Context(Rect):
def createFromSizeAndCorners(size,corners,**kwargs):
c=Context(size=size,**kwargs)
c.corners=corners
return c
def __init__(self,draw=None,**kwargs):
"""Create a context."""
if not draw: self.draw=Draw(**kwargs)
@@ -64,11 +69,11 @@ class Context(Rect):
def getSize(self):
"""Return the size of the surface shown."""
return self.draw.plane.getSize()
return self.draw.window.size
def setSize(self,size):
"""Set the size of the surface shown."""
self.draw.plane.setSize(size)
self.draw.window.size=size
def getUnits(self):
"""Return the units of the surface shown."""
@@ -98,6 +103,10 @@ class Context(Rect):
self.draw.plane.show(self.draw.window)
self.flip()
def __contains__(self,position):
"""Determine if a position is in the context."""
return self.draw.plane.contains(position,self.draw.window)
def show(self):
"""Show the plane on screen."""
self.draw.plane.show(self.draw.window)
@@ -155,7 +164,7 @@ class Context(Rect):
def transform(self,image,size):
"""Change the size of an image."""
pass
return self.draw.window.transform(image,size)
def getOpen(self):
return self.draw.window.open
@@ -179,21 +188,21 @@ class Context(Rect):
if self.open:
self.__enter__()
def getXmin(self):
"""Return xmin."""
return self.corners[0]
def getWidth(self):
"""Return the width of the window."""
return self.size[0]
def setXmin(self,x):
"""Set xmin."""
self.corners[0]=x
def setWidth(self,width):
"""Set the width of the window."""
self.size[0]=width
def getXmax(self,x):
"""Get xmax."""
return self.corners[2]
def getHeight(self):
"""Return the height of the window."""
return self.size[1]
def setXmax(self,x):
"""Set xmax."""
self.corners[2]=x
def setHeight(self,height):
"""Set the height of the window."""
self.size[1]=height
corners=property(getCorners,setCorners,"Allow the user to manipulate the corners of the surface easily.")
rect=property(getRect,setRect,"Allow the user to manipulate the rect of the surface easily.")
@@ -203,8 +212,8 @@ class Context(Rect):
units=property(getUnits,setUnits,"Allow the user to manipulate the units of the surface easily.")
keys=property(getKeys,"Allow the user to manipulate the keys of the surface easily.")
open=property(getOpen,setOpen)
xmin=property(getXmin,setXmin)
xmax=property(getXmax,setXmax)
width=property(getWidth,setWidth)
height=property(getHeight,setHeight)
@@ -213,4 +222,6 @@ Surface=Context
if __name__=="__main__":
context=Context()
context.corners=[0,0,1,1]
print(context.corners)
context()
+3 -1
View File
@@ -100,9 +100,11 @@ class Draw:
size=rect[2:]
position=self.plane.getToScreen(position,self.window)
size=self.plane.getToScreen(size,self.window)
self.window.draw.arcarc(screen,color,rect,start_angle,stop_angle,width)
self.window.draw.arc(screen,color,rect,start_angle,stop_angle,width)
def complex(self,screen,color,z,radius,**kwargs):
self.circle(screen,color,(z.real,z.imag),radius,**kwargs)
def show(self):
self.plane.showGrid(self.window)
+94 -19
View File
@@ -24,18 +24,13 @@ class Fourier:
self.graph_drawing=[]
self.graph_construction=[]
self.graph_display=[]
self.sample_precision=100
self.coefficients_number=100
self.display_number=100
self.period=100
self.mode=0
self.messages=['drawing', 'construction', 'display']
self.coefficients=[]
self.context.text.append("mode: "+self.messages[self.mode])
self.duration=None
self.time=0
self.max_step=100
self.step=0
self.speed=1/100
self.vectors=[]
def __call__(self):
@@ -72,12 +67,11 @@ class Fourier:
# self.graph_interpolation=self.sample(self.function_interpolation,len(self.graph_drawing))
elif self.mode==1: #construction
self.step+=1
self.time=self.speed*self.step
#print(self.time/self.duration)
if self.duration is not None:
if self.time>self.duration:
self.mode=2
self.graph_construction=self.discreteComplexComposeGraph(self.coefficients,self.time) #complex now
self.time=self.step/self.max_step
if self.step>self.max_step:
self.mode=2
#self.graph_construction=self.discreteComplexComposeGraph(self.coefficients,self.time) #complex now
self.graph_construction=self.numpyComposeConstructionGraph(self.coefficients,t=self.time)
self.vectors=self.getVectors([(0,0)]+self.graph_construction)
self.graph_display.append(self.graph_construction[-1])
@@ -99,7 +93,7 @@ class Fourier:
self.showGraph(self.graph_display,mycolors.BLUE)
self.showVectors([(0,0)]+self.graph_construction,self.vectors,mycolors.RED)
self.context.text.append("time: "+str(self.time))
#self.context.print("coefficients:"+str(self.coefficients),(1000,850),size=20,conversion=False,color=mycolors.GREEN)
elif self.mode==2:
self.showGraph(self.graph_display,mycolors.BLUE)
self.context.showConsole(nmax=10)
@@ -143,8 +137,13 @@ class Fourier:
self.graph_drawing=self.cleanGraph(self.graph_drawing)
#self.graph_drawing=self.takeGraphSamples(self.graph_drawing)[:]
print(self.graph_drawing)
self.coefficients=self.discreteComplexDecomposeGraph(self.graph_drawing)
self.graph_construction=self.discreteComplexComposeGraph(self.coefficients,0)
#self.coefficients=self.discreteComplexDecomposeGraph(self.graph_drawing)
self.graph_drawing=self.graph_drawing[:len(self.graph_drawing)-1+len(self.graph_drawing)%2]
self.coefficients=self.numpyFourierTransform(self.graph_drawing)
self.graph_drawing=self.numpyInverseFourierTransform(self.coefficients)
#print(len(self.coefficients))
#self.graph_construction=self.discreteComplexComposeGraph(self.coefficients,0)
self.graph_construction=self.graph_drawing
self.time=0
self.step=0
print(self.coefficients)
@@ -211,6 +210,20 @@ class Fourier:
p=self.context.point()
self.graph_drawing.append(p)
def threeBlueOneBrownFormula(self,graph):
c=[]
for n in range(len(graph)):
cn=sum([graph[n]])
def numpyFourierTransform(self,graph):
"""Return the fourier coefficients by doing a fourier transform for a given graph with the fft."""
z=[complex(*graph[i]) for i in range(len(graph))]
return np.fft.fft(z)
def numpyFourierTransform2D(self,graph,**kwargs):
"""Return the fourier coefficients by doing a fourier transform for a given graph with the fft2."""
return np.fft.fft2(graph,**kwargs)
def decompose(self,graph):
"""Decompose the points into 2 signals the coefficients corresponding to the drawing."""
x=[graph[i][0] for i in range(len(graph))]
@@ -280,6 +293,14 @@ class Fourier:
c.append(d)
return c
def numpyInverseFourierTransform(self,coefficients,**kwargs):
"""Return the fourier coefficients by doing a fourier transform for a given graph with the fft."""
return [(z.real,z.imag) for z in np.fft.ifft(coefficients,**kwargs)]
def numpyInverseFourierTransform2D(self,coefficients,**kwargs):
"""Create a graph using the coefficients under the form of a list of duos."""
return np.fft.ifft2(coefficients,**kwargs)
def scipyTranform(self,s):
"""Find the fourier transform using the scipy module."""
l=len(s)
@@ -373,14 +394,68 @@ class Fourier:
g.append((d.real,d.imag))
return g
def numpyComposeConstructionGraph2D(self,coefficients,t=0):
"""Uses the fourier coefficients of the fourier transform. to make the construciton graph."""
l=len(coefficients)
xs,ys=0,0
wo=2*math.pi
#wo=1
#wo=1/100
graph=[]
for i,c in enumerate(coefficients):
n=i
a,b=c
print("a:",a.real,a.imag)
#x=a.real*math.cos(n*wo*t)+a.imag*math.sin(n*wo*t)
#y=b.real*math.cos(n*wo*t)+b.imag*math.sin(n*wo*t)
x=a.real*math.cos(n*wo*t)
y=a.imag*math.sin(n*wo*t)
xs+=x; ys+=y
graph.append((xs,ys))
print("x,y:",x,y)
print("xs,ys:",xs,ys)
print(coefficients)
print(graph)
return graph
def numpyComposeConstructionGraph(self,coefficients,t=0):
"""Uses the fourier coefficients of the fourier transform. to make the construciton graph."""
l=len(coefficients)
xs,ys=0,0
wo=2*math.pi
#wo=1
#wo=1/10
graph=[]
#print("coefficients:")
#print(coefficients)
l=len(coefficients)
print(l)
h=l//2
for i in range(l):
n=int(((i+1)//2)*(-1)**(i+1))
print("n:",n)
z=coefficients[n+h]*cmath.exp(n*wo*t*1j)
print(z)
#print("z:",z.real,z.imag)
x=z.real
y=z.imag
xs+=x; ys+=y
graph.append((xs,ys))
#print("x,y:",x,y)
#print("xs,ys:",xs,ys)
print(graph)
return graph
if __name__=="__main__":
from mycontext import Context
context=Context(name="Application of the Fourier Transform.",fullscreen=False)
fourier=Fourier(context)
fourier.coefficients=[[0,1,2,0.5],[0,1,5,2],[0,-2,1,6],[0,-4,3,1]]
#fourier.coefficients=[(3+5j),(2+1j),(0-0.5j),(1+3.5j),(2-1j)]
#fourier.mode=1
#fourier.coefficients=[[0,1,2,0.5],[0,1,5,2],[0,-2,1,6],[0,-4,3,1]]
fourier.coefficients=np.array([(3+5j),(2+1j),(0-0.5j),(1+3.5j),dtype=complex])
#cx=[0+50j,0+18j,12+0j,-14+0j]
#cy=[-60-30j,0+8j,0-10j]
#fourier.coefficients=np.array(list(zip(cx,cy)))
fourier.mode=1
fourier()
@@ -0,0 +1,14 @@
class ImmutableBody(Body):
"""Define a body than cannot be moved by any other body."""
def __init__(self,*args,**kwargs):
super().__init(*args,**kwargs)
class Ground(ImmutableBody):
"""Define a ground that is an immutable body."""
def __init__(self,):
"""Create a ground using its line."""
self.mass=float('inf')
#(m1+m2)v=m1v1+m2v2
#m*v**2=m1*v1**2+m2*v2**2
@@ -0,0 +1,127 @@
"""
The goal of this program is to make an interpolation of the points of any
curve in order to make it a parametric function.
There are 2 main types of interpolations:
- Polynomial Interpolation:
- Bezier Interpolation:
"""
from marclib.polynomial import Polynomial
import numpy as np
#Deprectated function
def directInterpolation(points,t):
x=[pt[0] for pt in points]
y=[pt[1] for pt in points]
plx=Polynomial.createFromInterpolation(range(len(x)),x)
ply=Polynomial.createFromInterpolation(range(len(y)),y)
l=len(pts)
mst=100
class PolynomialInterpolation:
"""Make an interpolation using the lagrangian polynomial interpolator
over list of n-dimensional points."""
def __init__(self,points,create=True):
"""Create the interpolation using a list of n-dimensional points."""
self.points=points
if create: self.create()
def create(self):
"""Create the components useful for the interpolation which are the
split components and the lagrangian polynomials."""
self.createComponents()
self.createPolynomials()
def createComponents(self):
"""Split its components of each point in separate lists."""
self.components=[[pt[i] for pt in self.points] for i in range(len(self.points[0]))]
def createPolynomials(self):
"""Create its polynomials using its components."""
lpts=len(self.points)
self.polynomials=[Polynomial.createFromInterpolation(range(lpts),c) for c in self.components]
def __call__(self,t):
"""Evaluate the parametric interpolation for the input 't' between 0 and 1."""
lcps=len(self.components)
return tuple([self.polynomials[i](t) for i in range(lcps)])
def sample(self,n):
"""Make a sample of the interpolation for n points."""
lpts=len(self.points)
return [self(lpts*t) for t in np.linspace(0,1,n)]
class BezierInterpolation:
"""Make an interpolation using the bezier interpolation over a list of
n-dimensional points."""
def __init__(self,points,create=True):
"""Create the interpolation using a list of n-dimensional points."""
self.points=points
if create: self.create()
def create(self):
pass
def __call__(self):
pass
def sample(self,n):
"""Make a sample of the interpolation for n points."""
lpts=len(self.points)
return [self(lpts*t) for t in np.linspace(0,1,n)]
if __name__=="__main__":
#To show the points
from mycontext import Context
import mycolors
#To create the points
import random
context=Context()
#Parameters
h=1; w=1
xmin=-w
xmax=w
ymin=-h
ymax=h
n=5
#Creation of the points
pts=[(random.uniform(xmin,xmax),random.uniform(ymin,ymax)) for i in range(n)]
""" Tests:
Calculations for n points in dimension 2:
x=[pt[0] for pt in pts]
y=[pt[1] for pt in pts]
plx=Polynomial.createFromInterpolation(range(len(x)),x)
ply=Polynomial.createFromInterpolation(range(len(y)),y)
print(plx)
print(ply)
l=len(pts)
mst=100
npts=[(plx(l*st/mst),ply(l*st/mst)) for st in range(mst)]
grapher=Grapher(context,functions=[plx,ply])
"""
#Final version
interpolation=Interpolation(pts)
npts=interpolation.sample(200) #Sample 200 points by interpolation
#Main loop of the context
while context.open:
context.check()
context.control()
context.clear()
context.show()
context.draw.lines(context.screen,mycolors.GREEN,pts,connected=False)
context.draw.lines(context.screen,mycolors.YELLOW,npts,connected=False)
context.flip()
@@ -0,0 +1,123 @@
from mycontext import Context
from PIL import Image, ImageDraw
import numpy as np
import mycolors
from mymanager import SimpleManager
def mandelbrot(z,maxiter):
c=z
for n in range(maxiter):
if abs(z) > 2:
return n
z=z**2+c
return maxiter
def getMatrix(width=800,height=800,corners=[-2,-1,1,1],maxiter=80):
xmin,ymin,xmax,ymax=corners
xzoom=(xmax-xmin)/width
yzoom=(ymax-ymin)/height
matrix=np.zeros([width,height])
for x in range(0,width):
for y in range(0,height):
matrix[x][y]=mandelbrot(complex(xmin+x*xzoom,ymin+y*yzoom),maxiter)
return matrix
def showMatrixWithPIL(matrix,width=None,height=None,maxiter=80,save=True):
if (width is None) or (height is None):
width,height=[len(matrix),len(matrix[0])]
im = Image.new('RGB',(width,height),(0, 0, 0))
draw = ImageDraw.Draw(im)
for x in range(width):
for y in range(height):
color=int(matrix[x][y] * 255 / maxiter)
draw.point([x, y], (color, color, color))
if save: im.save('output.png', 'PNG')
im.show()
class Mandelbrot(SimpleManager):
def compute(self,z):
c=z
for n in range(self.maxiter):
if abs(z) > 2:
return n
z=z**2+c
return self.maxiter
def __init__(self,context,size,maxiter=80):
"""Create a set of mandelbrot using the size, the corners and the maxiter (maxiteration)."""
self.context=context
self.maxiter=maxiter
self.size=size
def buildMatrix(self):
"""Return the numpy matrix of the set."""
xmin,ymin,xmax,ymax=self.corners
xzoom=(xmax-xmin)/self.width
yzoom=(ymax-ymin)/self.height
self.matrix=np.zeros(self.size)
for x in range(self.width):
for y in range(self.height):
self.matrix[x][y]=self.compute(complex(xmin+x*xzoom,ymin+y*yzoom))
def showWithPIL(self,save=True):
"""Show the set with PIL using the matrix."""
im = Image.new('RGB',(self.width,self.height),(0, 0, 0))
draw = ImageDraw.Draw(im)
for x in range(self.width):
for y in range(self.height):
color=int(self.matrix[x][y] * 255 / self.maxiter)
draw.point([x, y], (color, color, color))
if save: im.save('output.png', 'PNG')
im.show()
def showSet(self):
"""Show the mandelbrot set on the context."""
for x in range(self.width):
for y in range(self.height):
c=int(self.matrix[x][y] * 255 / self.maxiter)
self.context.draw.rect(self.context.screen,(c,c,c),[x,y,1,1])
def update(self):
"""Update the mandelbrot set depending on the corners."""
self.buildMatrix()
def show(self):
"""Show the mandelbrot set."""
self.context.refresh()
self.context.control()
self.showSet()
self.context.flip()
def getCorners(self):
return self.context.corners
def getWidth(self):
return self.size[0]
def getHeight(self):
return self.size[1]
#Properties
corners=property(getCorners)
height=property(getHeight)
width=property(getWidth)
if __name__=="__main__":
context_size=[800,600]
mandelbrot_size=[200,150]
corners=[-2,-1,1,1]
context=Context.createFromSizeAndCorners(context_size,corners,name="Mandelbrot") #width,height=context.size
print(context.corners)
print(context.position)
print([0,0] in context)
#width=800;height=600;maxiter=20
#matrix=getMatrix(width,height,maxiter=maxiter)
#showMatrixWithPIL(matrix,width,height,maxiter=maxiter)
m=Mandelbrot(context,mandelbrot_size)
m()
@@ -0,0 +1,14 @@
import numpy as np
class VisualGraph:
"""Wikipedia: In mathematics, and more specifically in graph theory, a graph
is a structure amounting to a set of objects in which some pairs of the
objects are in some sense "related". The objects correspond to mathematical
abstractions called vertices (also called nodes or points) and each of the
related pairs of vertices is called an edge (also called link or line).[1]
Typically, a graph is depicted in diagrammatic form as a set of dots or
circles for the vertices, joined by lines or curves for the edges. Graphs
are one of the objects of study in discrete mathematics."""
def __init__(self,matrix):
"""Create a graph using its
self.matrix=matrix
@@ -67,14 +67,16 @@ class Grapher(SimpleManager):
def sampleFunctions(self,functions):
"""Sample all the functions one by one."""
return [self.sampleFunction(function) for function in functions]
ymin=self.context.ymin
ymax=self.context.ymax
return [self.sampleFunction(function,ymin,ymax) for function in functions]
def sampleFunction(self,function):
def sampleFunction(self,function,ymin,ymax):
"""Return n points of the graph."""
xmin,xmax=self.getInterval()
n=self.sample_number
xl=np.linspace(xmin,xmax,n)
return [(x,function(x)) for x in xl]
return [(x,function(x)) for x in xl if ymin<function(x)<ymax]
def cleverlySampleFunction(self,function):
"""Sample a function in an optimized way to get the nicest visualisation possible with the less points as possible."""
@@ -90,7 +92,7 @@ class Grapher(SimpleManager):
self.context.clear()
self.context.control()
self.context.show()
self.showGraphs(self.graphs)
self.showGraphs(self.functions)
#Its just for a demo, it will be removed later
if "points" in self.__dict__:
self.showPoints()
+8 -6
View File
@@ -223,19 +223,21 @@ class Plane:
def getCorners(self,window):
"""Return the corners of the present view."""
wsx,wsy=window.size
ux,uy=self.units
x,y=self.position
lx,ly=wsx/ux,wsy/uy
return [x-lx/2,y-ly/2,x+lx/2,y+ly/2]
mx,my=self.getFromScreen([0,wsy],window)
Mx,My=self.getFromScreen([wsx,0],window)
return (mx,my,Mx,My)
def setCorners(self,corners,window):
"""Change the actual corners of the plane by changing its position and units."""
wsx,wsy=window.size
xmin,ymin,xmax,ymax=corners
xmin,ymin=self.getToScreen([xmin,ymin],window)
xmax,ymax=self.getToScreen([xmax,ymax],window)
x,y,sx,sy=self.getCoordonnatesFromCorners([xmin,ymin,xmax,ymax])
self.position=[x,y]
self.units=[wsx//sx,wsy//sy]
wsx,wsy=window.size
self.position=[xmin+(xmax-xmin)/2,ymin+(ymax-ymin)/2]
self.units=[wsx/(xmax-xmin),wsy/(ymax-ymin)]
#The following functions are static methods
@@ -1,4 +1,4 @@
from mysurface import Surface
from mycontext import Surface
import math
import cmath
@@ -50,7 +50,7 @@ class Mandelbrot:
def show(self,surface,precision=[10,10]):
"""Show the mandelbrot set on the surface."""
wsx,wsy=surface.draw.window.size
corners=surface.draw.plane.getPlaneCorners(surface.draw.window)
corners=surface.draw.plane.getCorners(surface.draw.window)
mx,my,Mx,My=corners
px,py=precision
ux,uy=surface.draw.plane.units
Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

+25 -1
View File
@@ -1 +1,25 @@
from
from mycontext import Context
import mycolors
import cmath
import random
cx=[0+50j,0+18j,12+0j,-14+0j]
cy=[-60-30j,0+8j,0-10j,0]
a=list(zip(cx,cy))
print(a)
context=Context()
n=100
l=[complex(random.uniform(-1,1),random.uniform(-1,1)) for i in range(n)]
while context.open:
context.check()
context.control()
context.clear()
context.show()
for e in l:
z=cmath.exp(complex(e))
context.draw.complex(context.screen,mycolors.WHITE,z,0.1)
context.flip()
+74
View File
@@ -0,0 +1,74 @@
from __future__ import division
import random as rd
from math import exp,log
import math
BLUE = ( 0, 0,255)
RED = (255, 0, 0)
GREEN = ( 0,255, 0)
YELLOW = (255,255, 0)
BLACK = ( 0, 0, 0)
WHITE = (255,255,255)
GREY = (100,100,100)
PURPLE = (100, 0,100)
ORANGE = (255,165, 0)
BROWN = (160, 82, 45)
HALFGREY = ( 50, 50, 50)
DARKGREY = ( 20, 20, 20)
DARKRED = ( 10, 10, 10)
DARKGREEN = ( 0,100, 0)
DARKBLUE = ( 0, 0,100)
LIGHTRED = (255,200,200)
LIGHTGREEN = (200,255,200)
LIGHTBLUE = (200,200,255)
LIGHTBROWN = (229,219,222)
LIGHTGREY = (200,200,200)
BEIGE = (199,175,138)
sigmoid = s = lambda x:1/(1+math.exp(-x))
reverse_sigmoid = lambda x:log(x/(1-x))
#r=reverse_sigmoid()
bijection = lambda x,e,s:(x-e[0])/(e[1]-e[0])*(s[1]-s[0])+s[0]
random = lambda : tuple([rd.randint(0,255) for i in range(3)])
reverse = lambda color: tuple([255-c for c in color])
darken = lambda color,n=0: tuple([int(c*sigmoid(n/10)) for c in color])
lighten = lambda color,n=0: tuple([int(255-(255-c)*sigmoid(n/10)) for c in color])
mix = lambda cl1,cl2: tuple([(c1+c2)//2 for (c1,c2) in zip(cl1,cl2)])
substract = lambda cl1,cl2: tuple([max(min(2*c1-c2,255),0) for (c1,c2) in zip(cl1,cl2)])
increase = lambda color,n=2: tuple([int(255*exp(n*log(c/255))) for c in color])
def setFromWavelength(wavelength):
"""Return a color using wavelength."""
gamma,max_intensity=0.80,255
def adjust(color, factor):
if color==0: return 0
else: return round(max_intensity*pow(color*factor,gamma))
if 380<=wavelength<=440: r,g,b=-(wavelength-440)/(440-380),0,1
elif 440<=wavelength<=490: r,g,b=0,(wavelength-440)/(490-440),1
elif 490<=wavelength<=510: r,g,b=0,1,-(wavelength-510)/(510-490)
elif 510<=wavelength<=580: r,g,b=(wavelength-510)/(580-510),1,0
elif 580<=wavelength<=645: r,g,b=1,-(wavelength-645)/(645-580),0
elif 645<=wavelength<=780: r,g,b=1,0,0
else: r,g,b=0,0,0
if 380<=wavelength<=420: factor=0.3+0.7*(wavelength-380)/(420-380)
elif 420<=wavelength<=701: factor=1
elif 701<=wavelength<=780: factor=0.3+0.7*(780-wavelength)/(780-700)
else: factor=0
r,g,b=adjust(r,factor),adjust(g,factor),adjust(b,factor)
return (r,g,b)
#if __name__=="__main__":
#print(darken(RED,10))
#print(mix(YELLOW,RED))
#print(reverse(LIGHTBROWN))
#print(substract(LIGHTBROWN,ORANGE))
#print(increase(LIGHTBROWN))
#for i in range(380,780,10):
# print(setFromWavelength(i))
#print("mycolors imported")
+52
View File
@@ -0,0 +1,52 @@
# Programme : mandelbrot.py
# Langage : Python 3.6 - Pygame 1.9
# Auteur : Mathieu
# Description : Calcule et affiche la fractale de Mandelbrot en noir et blanc
import pygame
# Constantes
MAX_ITERATION = 50 # nombre d'itérations maximales avant de considérer que la suite converge
XMIN, XMAX, YMIN, YMAX = -2, +0.5, -1.25, +1.25 # bornes du repère
LARGEUR, HAUTEUR = 500, 500 # taille de la fenêtre en pixels
# Initialisation et création d'une fenêtre aux dimensions spécifiéés munie d'un titre
pygame.init()
screen = pygame.display.set_mode((LARGEUR,HAUTEUR))
pygame.display.set_caption("Fractale de Mandelbrot")
# Création de l'ensemble de Mandelbrot
# Principe : on balaye l'écran pixel par pixel en convertissant le pixel en un point du plan de notre repère
# Si la suite converge, le point appartient à l'ensemble de Mandelbrot et on colore le pixel en noir
# Sinon la suite diverge, le point n'appartient pas à l'ensemble et on colore le pixel en blanc
for y in range(HAUTEUR):
for x in range(LARGEUR):
# Les deux lignes suivantes permettent d'associer à chaque pixel de l'écran de coordonnées (x;y)
# un point C du plan de coordonnées (cx;cy) dans le repère défini par XMIN:XMAX et YMIN:YMAX
cx = (x * (XMAX - XMIN) / LARGEUR + XMIN)
cy = (y * (YMIN - YMAX) / HAUTEUR + YMAX)
xn = 0
yn = 0
n = 0
while (xn * xn + yn * yn) < 4 and n < MAX_ITERATION: # on teste que le carré de la distance est inférieur à 4 -> permet d'économiser un calcul de racine carrée coûteux en terme de performances
# Calcul des coordonnes de Mn
tmp_x = xn
tmp_y = yn
xn = tmp_x * tmp_x - tmp_y * tmp_y + cx
yn = 2 * tmp_x * tmp_y + cy
n = n + 1
if n == MAX_ITERATION:
screen.set_at((x, y), (0, 0, 0)) # On colore le pixel en noir -> code RGB : (0,0,0)
else:
screen.set_at((x, y), (255, 255, 255)) # On colore le pixel en blanc -> code RGB : (255,255,255)
pygame.display.flip() # Mise à jour et rafraîchissement de la fenêtre graphique pour affichage
# Boucle infinie permettant d'afficher à l'écran la fenêtre graphique
# Sans ça, la fenêtre apparaît et disparaît aussitôt
loop = True
while loop:
for event in pygame.event.get():
if event.type == pygame.QUIT: # Pour quitter l'application en fermant la fenêtre
loop = False
elif event.type == pygame.MOUSEBUTTONDOWN:
p = pygame.mouse.get_pos()
px = (p[0] * (XMAX - XMIN) / LARGEUR + XMIN)
py = (p[1] * (YMIN - YMAX) / HAUTEUR + YMAX)
print("({};{})".format(px,py))
pygame.quit()
+87
View File
@@ -0,0 +1,87 @@
#from mycontext import Context
from PIL import Image, ImageDraw
import numpy as np
import colors
def getDiscreteColoredArray(array,color1=colors.WHITE,color2=colors.BLACK):
f=lambda n:color1 if n==1 else color2
return f(array)
def uselessNameSpace():
for y in range(HAUTEUR):
for x in range(LARGEUR):
# Les deux lignes suivantes permettent d'associer à chaque pixel de l'écran de coordonnées (x;y)
# un point C du plan de coordonnées (cx;cy) dans le repère défini par XMIN:XMAX et YMIN:YMAX
cx = (x * (XMAX - XMIN) / LARGEUR + XMIN)
cy = (y * (YMIN - YMAX) / HAUTEUR + YMAX)
xn = 0
yn = 0
n = 0
while (xn * xn + yn * yn) < 4 and n < MAX_ITERATION: # on teste que le carré de la distance est inférieur à 4 -> permet d'économiser un calcul de racine carrée coûteux en terme de performances
# Calcul des coordonnes de Mn
tmp_x = xn
tmp_y = yn
xn = tmp_x * tmp_x - tmp_y * tmp_y + cx
yn = 2 * tmp_x * tmp_y + cy
def showMatrixWithScreen(screen,array,width=None,height=None):
if not width or not height:
width,height=[len(array),len(array[0])]
for x in range(width):
for y in range(height):
screen.set_at((x, y),array[x][y])
def showMatrixWithContext(context,array,width=None,height=None):
if not width or not height:
width,height=[len(array),len(array[0])]
for x in range(width):
for y in range(height):
context.draw.square()
def mandelbrot(z,maxiter):
c=z
for n in range(maxiter):
if abs(z) > 2:
return n
z=z**2+c
return maxiter
def getMatrix(width=800,height=800,corners=[-2,-1,1,1],maxiter=80):
xmin,ymin,xmax,ymax=corners
xzoom=(xmax-xmin)/width
yzoom=(ymax-ymin)/height
matrix=np.zeros([width,height])
for x in range(0,width):
for y in range(0,height):
matrix[x][y]=mandelbrot(complex(xmin+x*xzoom,ymin+y*yzoom),maxiter)
return matrix
def showMatrixWithPIL(matrix,width=None,height=None,maxiter=80,save=True):
if (width is None) or (height is None):
width,height=[len(matrix),len(matrix[0])]
im = Image.new('RGB',(width,height),(0, 0, 0))
draw = ImageDraw.Draw(im)
for x in range(width):
for y in range(height):
color=int(matrix[x][y] * 255 / maxiter)
draw.point([x, y], (color, color, color))
if save: im.save('output.png', 'PNG')
im.show()
if __name__=="__main__":
#context=Context()
#width,height=context.size
width=800;height=600;maxiter=20
matrix=getMatrix(width,height,maxiter=maxiter)
showMatrixWithPIL(matrix,width,height,maxiter=maxiter)
+46
View File
@@ -0,0 +1,46 @@
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import colors
#%matplotlib inline
settings=[-2.0,0.5,-1.25,1.25,3,3,80]
def mandelbrot(z,maxiter):
c = z
for n in range(maxiter):
if abs(z) > 2:
return n
z = z*z + c
return maxiter
def mandelbrot_set(xmin,xmax,ymin,ymax,width,height,maxiter):
r1 = np.linspace(xmin, xmax, width)
r2 = np.linspace(ymin, ymax, height)
return (r1,r2,[mandelbrot(complex(r, i),maxiter) for r in r1 for i in r2])
def mandelbrot_image(xmin,xmax,ymin,ymax,width=3,height=3,maxiter=80,cmap='hot'):
print("Initiating the mandelbrot image.")
dpi = 72 #Zoom of the image
img_width = dpi * width #Find the width of the image using the zoom and the width of the set
img_height = dpi * height #Same operation for the height
x,y,z = mandelbrot_set(xmin,xmax,ymin,ymax,img_width,img_height,maxiter) #Find the set
print("The set is done.")
print(type(z[0]))
fig, ax = plt.subplots(figsize=(width, height),dpi=72) #get plt components
ticks = np.arange(0,img_width,3*dpi) #find the steps
x_ticks = xmin + (xmax-xmin)*ticks/img_width #split the x axis
plt.xticks(ticks, x_ticks)
y_ticks = ymin + (ymax-ymin)*ticks/img_width #split the y axis
plt.yticks(ticks, y_ticks)
print("Image settings are done.")
norm = colors.PowerNorm(0.3) #Cool colors i guess
ax.imshow(z,cmap=cmap,origin='lower',norm=norm) #create a dope heat map
print("Image is done.")
mandelbrot_image(-2.0,0.5,-1.25,1.25,maxiter=80,cmap='gnuplot2')
#img=Image.fromarray(ms,'RGB')
#img.show()
+31
View File
@@ -0,0 +1,31 @@
from PIL import Image, ImageDraw
from mandelbrot import mandelbrot, MAX_ITER
# Image size (pixels)
WIDTH = 600
HEIGHT = 400
# Plot window
RE_START = -2
RE_END = 1
IM_START = -1
IM_END = 1
palette = []
im = Image.new('RGB', (WIDTH, HEIGHT), (0, 0, 0))
draw = ImageDraw.Draw(im)
for x in range(0, WIDTH):
for y in range(0, HEIGHT):
# Convert pixel coordinate to complex number
c = complex(RE_START + (x / WIDTH) * (RE_END - RE_START),
IM_START + (y / HEIGHT) * (IM_END - IM_START))
# Compute the number of iterations
m = mandelbrot(c)
# The color depends on the number of iterations
color = 255 - int(m * 255 / MAX_ITER)
# Plot the point
draw.point([x, y], (color, color, color))
im.save('output.png', 'PNG')
+58
View File
@@ -0,0 +1,58 @@
from PIL import Image, ImageDraw
import numpy as np
#from mandelbrot import mandelbrot, MAX_ITER
MAX_ITER = 80
def mandelbrot(c,maxiter):
z = 0
n = 0
while abs(z) <= 2 and n < maxiter:
z = z**2 + c
n += 1
return n
# Image size (pixels)
def showPicture(corners=[-2,-1,1,1],width=600,height=400,maxiter=80):
xmin,ymin,xmax,ymax=corners
im = Image.new('RGB', (width,height), (0, 0, 0))
draw = ImageDraw.Draw(im)
xlength=xmax-xmin
ylenght=ymax-ymin
#from pixel to complex
xzoom=xlength/width
yzoom=ylenght/height
for x in range(width):
for y in range(height):
# Convert pixel coordinate to complex number
c = complex(xmin+x*xzoom,ymin+y*yzoom)
# Compute the number of iterations
m = mandelbrot(c,maxiter)
# The color depends on the number of iterations
color = int(m * 255 / maxiter)
# Plot the point
draw.point([x, y], (color, color, color))
im.save('output.png', 'PNG')
im.show()
def getMatrix(corners=[-2,-1,1,1],width=600,height=400,maxiter=80):
xmin,ymin,xmax,ymax=corners
xzoom=(xmax-xmin)/width
yzoom=ymax-ymin/height
matrix=np.zeros([width,height])
for x in range(0,width):
for y in range(0,height):
c = complex(xmin+x*xzoom,ymin+y*yzoom)
m = mandelbrot(c,maxiter)
matrix[x,y]=m
return matrix
#matrix=getMatrix()
#print(len(matrix))
showPicture()
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB