| HomeTortue graphiqueGPanelRobotique WebTigerPython |
| Python - Online |
![]()
SIMULATION D'UN ESSAIM |
Dans ton programme, tu détermines les cellules voisines en sélectionnant, parmi les quatre cellules adjacentes, celles qui ne se trouvent ni sur un mur ni à l'extérieur de la grille. Un oiseau qui se déplace dans un groupe cherche, d'une part, à rester proche de ses voisins et, d'autre part, à éviter les collisions. Son comportement peut être décrit par les trois règles suivantes : 1. Séparation: Chaque Actor maintient une certaine distance par rapport à ses voisins afin d'éviter les collisions. Le vecteur d'accélération de l'Actor est dirigé dans le sens opposé au vecteur résultant de la somme des positions de ses voisins. 2. Alignement: L'objectif est d'adapter la vitesse et la direction de l'Actor à celles de ses voisins. Le vecteur vitesse de l'Actor est déterminé à partir de la moyenne des vecteurs vitesse de ses voisins. 3. Cohésion: L'objectif est de maintenir la cohésion du groupe et de permettre à chaque Actor de rester aussi proche que possible de ses voisins. Le vecteur d'accélération de l'Actor est dirigé vers le centre de masse commun de ses voisins. Programme: # Swarm.py from gamegrid import * import math import random class Tree(Actor): def __init__(self): Actor.__init__(self, "sprites/tree1.png") class Bird(Actor): def __init__(self): Actor.__init__(self, True, "sprites/arrow1.png") self.r = GGVector(0, 0) # Position self.v = GGVector(0, 0) # Velocity self.a = GGVector(0, 0) # Acceleration # Called when actor is added to gamegrid def reset(self): self.r.x=self.getX() self.r.y=self.getY() self.v.x=startVelocity*math.cos(math.radians(self.getDirection())) self.v.y=startVelocity*math.sin(math.radians(self.getDirection())) # ----------- cohesion --------------- def cohesion(self, distance): return self.getCenterOfMass(distance).sub(self.r) # ----------- alignment -------------- def alignment(self, distance): align = self.getAverageVelocity(distance) align = align.sub(self.v) return align # ----------- separation ------------- def separation(self, distance): repulse = GGVector() # ------ from birds ------ for p in birdPositions: dist = p.sub(self.r) d = dist.magnitude() if d < distance and d != 0: repulse = repulse.add(dist.mult((d-distance)/d)) # ------ from trees ------ trees = self.gameGrid.getActors(Tree) for actor in trees: p = GGVector(actor.getX(), actor.getY()) dist = p.sub(self.r) d = dist.magnitude() if d < distance and d != 0: repulse = repulse.add(dist.mult((d-distance)/d)) return repulse # ----------- wall interaction ------- def wallInteraction(self): width = self.gameGrid.getWidth() height = self.gameGrid.getHeight() acc = GGVector() if self.r.x < wallDist: distFactor = (wallDist - self.r.x) / wallDist acc = GGVector(wallWeight * distFactor, 0) if width - self.r.x < wallDist: distFactor = ((width - self.r.x)-wallDist)/wallDist acc = GGVector(wallWeight * distFactor, 0) if self.r.y < wallDist: distFactor = (wallDist - self.r.y) / wallDist acc = GGVector(0, wallWeight * distFactor) if height - self.r.y < wallDist: distFactor = ((height - self.r.y)-wallDist)/wallDist acc = GGVector(0, wallWeight * distFactor) return acc def getPosition(self): return self.r def getVelocity(self): return self.v def getCenterOfMass(self, distance): center = GGVector() sum = 0 for p in birdPositions: dist = p.sub(self.r) d = dist.magnitude() if d < distance: center = center.add(p) sum += 1 if sum != 0: return center.mult(1.0/sum) else: return center def getAverageVelocity(self, distance): avg = GGVector() sum = 0 for i in range(len(birdPositions)): p = birdPositions[i] if (self.r.x - p.x)*(self.r.x-p.x) + \ (self.r.y - p.y)*(self.r.y-p.y)<distance*distance: avg = avg.add(birdVelocities[i]); sum += 1 return avg.mult(1.0/sum) def limitSpeed(self): m = self.v.magnitude() if m < minSpeed: self.v = self.v.mult(minSpeed / m) if m > maxSpeed: self.v = self.v.mult(minSpeed / m) def setAcceleration(self): self.a = self.cohesion(cohDist).mult(cohWeight) self.a = self.a.add(self.separation(sepDist).mult(sepWeight)) self.a = self.a.add(self.alignment(aligDist).mult(aligWeight)) self.a = self.a.add(self.wallInteraction()) def act(self): self.setAcceleration() self.v = self.v.add(self.a) # new velocity self.limitSpeed() self.r = self.r.add(self.v) # new position self.setDirection(int(math.degrees(self.v.getDirection()))) self.setLocation(Location(int(self.r.x), int(self.r.y))) # global section def populateTrees(number): blockSize = 70 treesPerBlock = 10 for block in range(number // treesPerBlock): x = getRandomNumber(800 // blockSize) * blockSize y = getRandomNumber(600 // blockSize) * blockSize for t in range(treesPerBlock): dx = getRandomNumber(blockSize) dy = getRandomNumber(blockSize) addActor(Tree(), Location(x + dx, y + dy)) def generateBirds(number): for i in range(number): addActorNoRefresh(Bird(), getRandomLocation(), getRandomDirection()) onAct() # Initialize birdPositions, birdVelocities def onAct(): global birdPositions, birdVelocities # Update bird positions and velocities birdPositions = [] birdVelocities = [] for b in getActors(Bird): birdPositions.append(b.getPosition()) birdVelocities.append(b.getVelocity()) def getRandomNumber(limit): return random.randint(0, limit-1) # coupling constants cohDist = 100 cohWeight = 0.01 aligDist = 30 aligWeight = 1 sepDist = 30 sepWeight = 0.2 wallDist = 20 wallWeight = 2 maxSpeed = 20 minSpeed = 10 startVelocity = 10 numberTrees = 100 numberBirds = 50 birdPositions = [] birdVelocities = [] makeGameGrid(800, 600, 1, False) registerAct(onAct) setSimulationPeriod(10) setBgColor(Color.blue) setTitle("Swarm Simulation") show() populateTrees(numberTrees) generateBirds(numberBirds) doRun() |
MACHINE À EXPRESSO |
Dans la vie quotidienne, tu rencontres de nombreux appareils et machines qui peuvent être considérés comme des automates. Parmi ceux-ci figurent les distributeurs de boissons, les machines à laver, les distributeurs automatiques de billets, etc. En tant qu'ingénieur ou informaticien, tu conçois un tel automate en considérant qu'il passe progressivement d'un état actuel à un état suivant. Ce changement d'état dépend des données fournies par les capteurs ainsi que de l'utilisation des boutons et des interrupteurs. |
Programme: #Espresso.py from gamegrid import * def pressEvent(e): global state loc = toLocationInGrid(e.getX(), e.getY()) if loc == Location(1, 2): # off state = "OFF" led.show(0) coffee.hide() elif loc == Location(2, 2): # on if state == "OFF": state = "STANDBY" led.show(1) elif loc == Location(4, 2): # stop if state == "WORKING": state = "STANDBY" coffee.hide() elif loc == Location(5, 2): # work if state == "STANDBY": state = "WORKING" coffee.show() setTitle("State: " + str(state)) refresh() state = "OFF" makeGameGrid(7, 11, 50, None, "sprites/espresso.png", False, mousePressed = pressEvent) show() setTitle("State: " + str(state)) led = Actor("sprites/lightout.gif", 2) addActor(led, Location(3, 3)) coffee = Actor("sprites/coffee.png") addActor(coffee, Location(3, 6)) coffee.hide() refresh() |
![]()