diff --git a/Game Structure/geometry/version4/body test1.py b/Game Structure/geometry/version4/body test1.py index 4d7b47d..6c96833 100644 --- a/Game Structure/geometry/version4/body test1.py +++ b/Game Structure/geometry/version4/body test1.py @@ -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 diff --git a/Game Structure/geometry/version4/fermi's elephant.py b/Game Structure/geometry/version4/fermi's elephant.py new file mode 100644 index 0000000..6a9abad --- /dev/null +++ b/Game Structure/geometry/version4/fermi's elephant.py @@ -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() diff --git a/Game Structure/geometry/version4/mybody.py b/Game Structure/geometry/version4/mybody.py index cff3aa3..059ec57 100644 --- a/Game Structure/geometry/version4/mybody.py +++ b/Game Structure/geometry/version4/mybody.py @@ -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() diff --git a/Game Structure/geometry/version4/mycontext.py b/Game Structure/geometry/version4/mycontext.py index 9073eab..4e6d3ed 100644 --- a/Game Structure/geometry/version4/mycontext.py +++ b/Game Structure/geometry/version4/mycontext.py @@ -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() diff --git a/Game Structure/geometry/version4/mydraw.py b/Game Structure/geometry/version4/mydraw.py index 64d2c84..214ee44 100644 --- a/Game Structure/geometry/version4/mydraw.py +++ b/Game Structure/geometry/version4/mydraw.py @@ -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) diff --git a/Game Structure/geometry/version4/myfourier.py b/Game Structure/geometry/version4/myfourier.py index 85ce873..62bb03d 100644 --- a/Game Structure/geometry/version4/myfourier.py +++ b/Game Structure/geometry/version4/myfourier.py @@ -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() diff --git a/Game Structure/geometry/version4/myimmutablebody.py b/Game Structure/geometry/version4/myimmutablebody.py new file mode 100644 index 0000000..9ef6e0e --- /dev/null +++ b/Game Structure/geometry/version4/myimmutablebody.py @@ -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 diff --git a/Game Structure/geometry/version4/myinterpolation.py b/Game Structure/geometry/version4/myinterpolation.py new file mode 100644 index 0000000..f13e411 --- /dev/null +++ b/Game Structure/geometry/version4/myinterpolation.py @@ -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() diff --git a/Game Structure/geometry/version4/mymandelbrot.py b/Game Structure/geometry/version4/mymandelbrot.py new file mode 100644 index 0000000..ffb891a --- /dev/null +++ b/Game Structure/geometry/version4/mymandelbrot.py @@ -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() diff --git a/Game Structure/geometry/version4/mymathgraph.py b/Game Structure/geometry/version4/mymathgraph.py new file mode 100644 index 0000000..ab00818 --- /dev/null +++ b/Game Structure/geometry/version4/mymathgraph.py @@ -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 diff --git a/Game Structure/geometry/version4/mynewgrapher.py b/Game Structure/geometry/version4/mynewgrapher.py index 21fa7d6..0dd7cf2 100644 --- a/Game Structure/geometry/version4/mynewgrapher.py +++ b/Game Structure/geometry/version4/mynewgrapher.py @@ -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 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() diff --git a/Mandelbrot/mandelbrot tools.py b/Mandelbrot/mandelbrot tools.py new file mode 100644 index 0000000..517816e --- /dev/null +++ b/Mandelbrot/mandelbrot tools.py @@ -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) diff --git a/Mandelbrot/mandelbrot1.py b/Mandelbrot/mandelbrot1.py new file mode 100644 index 0000000..a8e6c81 --- /dev/null +++ b/Mandelbrot/mandelbrot1.py @@ -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() diff --git a/Mandelbrot/mandelbrot2 bis.py b/Mandelbrot/mandelbrot2 bis.py new file mode 100644 index 0000000..c0ba024 --- /dev/null +++ b/Mandelbrot/mandelbrot2 bis.py @@ -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') diff --git a/Mandelbrot/mandelbrot2.py b/Mandelbrot/mandelbrot2.py new file mode 100644 index 0000000..39be6ee --- /dev/null +++ b/Mandelbrot/mandelbrot2.py @@ -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() diff --git a/Mandelbrot/output.png b/Mandelbrot/output.png new file mode 100644 index 0000000..d60f0ac Binary files /dev/null and b/Mandelbrot/output.png differ