0% found this document useful (0 votes)
10 views16 pages

Simulation Poisson Sauvegarde

This document contains code for simulating fish and predators in a 3D environment. It defines Fish and Predator classes with properties like position, direction, and methods for drawing and updating. It initializes populations of each in a 3D world and includes functions for updating their positions based on behaviors like attraction, repulsion, and alignment with neighbors. Sliders are also implemented to control parameters of the simulation.

Uploaded by

mariusaudenis
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views16 pages

Simulation Poisson Sauvegarde

This document contains code for simulating fish and predators in a 3D environment. It defines Fish and Predator classes with properties like position, direction, and methods for drawing and updating. It initializes populations of each in a 3D world and includes functions for updating their positions based on behaviors like attraction, repulsion, and alignment with neighbors. Sliders are also implemented to control parameters of the simulation.

Uploaded by

mariusaudenis
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

# -*- coding: utf-8 -*-

"""

Created on Wed Feb 28 20:20:49 2024

@author: Maintenant Pret

"""

import numpy as np

import os

import networkx as nx

import pygame

import sys

import random

from scipy.spatial.distance import cdist

import math

thorus=True

#create random fish world

new_working_directory = r'C:\Users\Maintenant Pret\OneDrive\Bureau\projet prog'

# Change the working directory

os.chdir(new_working_directory)

X=1920

Y=1080

Z=1000

numb_fish = 100
numb_pred = 0

predators_repulsion=1000

threshold_angle = np.radians(70)

turn_probability=20

pygame.display.set_caption("Sliders")

WIDTH, HEIGHT = X,Y

# Colors

WHITE = (255, 255, 255)

BLACK = (0, 0, 0)

RED = (255, 0, 0)

# Slider parameters

slider_width = 200

slider_height = 20

slider_x = 50

slider_spacing = 40

slider_min = 0

slider_max = 500

# Function to draw sliders

slider_x = WIDTH - slider_width - 50 # Adjust as needed for spacing from the right edge

# Function to draw sliders with updated x-coordinate

def draw_slider(name, value, y):

# Draw slider label

label = font.render(name + ': ' + str(value), True, BLACK)


screen.blit(label, (WIDTH - slider_width - 10, y)) # Adjust x-coordinate

# Draw slider

pygame.draw.rect(screen, BLACK, (slider_x, y + 30, slider_width, slider_height))

pygame.draw.rect(screen, RED, (slider_x, y + 30, (value / slider_max) * slider_width, slider_height))

def rotate_vector(vector, angle):

axis=random.randint(1,3)

angle_radians = math.radians(angle)

if axis == 1:

rotation_matrix = np.array([[1, 0, 0], [0, math.cos(angle_radians), -math.sin(angle_radians)],[0,


math.sin(angle_radians), math.cos(angle_radians)]])

elif axis == 2:

rotation_matrix = np.array([[math.cos(angle_radians), 0, math.sin(angle_radians)], [0, 1, 0],[-


math.sin(angle_radians), 0, math.cos(angle_radians)]])

elif axis == 3:

rotation_matrix = np.array([[math.cos(angle_radians), -math.sin(angle_radians), 0],


[math.sin(angle_radians), math.cos(angle_radians), 0],[0, 0, 1]])

rotated_vector = np.dot(rotation_matrix, vector)

return rotated_vector

def in_vision_field(animal1,animal2,half_angle):

apex_to_point=np.array([animal2.x,animal2.y,animal2.z])-np.array([animal1.x,animal.y,animal.z])

cos_angle = np.dot(apex_to_point, animal1.direction) / (np.linalg.norm(apex_to_point) *


np.linalg.norm(animal1.direction))

angle = np.arccos(np.clip(cos_angle, -1, 1))

if angle <= np.radians(half_angle):

return True
else:

return False

class fish:

speed = 30

color = (255,255,255)

def __init__(self, x, y,z, direction):

self.x = x

self.y = y

self.z=z

self.direction = direction

self.direction_vectors = []

def draw(self, screen):

size_adjust = (self.z / Z)+0.5

if np.linalg.norm(self.direction) != 1.0:

self.direction = self.direction / np.linalg.norm(self.direction)

dx, dy = self.direction[:2]

vertices = [

np.array([self.x, self.y])-20*size_adjust *np.array([dx, dy]),

np.array([self.x, self.y])+ 3*np.array([dy, -dx])*size_adjust,

np.array([self.x, self.y])+3*np.array([-dy, dx])*size_adjust

head = np.linalg.norm(np.array([dy, -dx]) )*size_adjust

# Scale the RGB components based on z


r = min(255, max(0, int(fish.color[0] * (self.z / Z))))

g = min(255, max(0, int(fish.color[1] * (self.z / Z))))

b = min(255, max(0, int(fish.color[2] * (self.z / Z))))

pygame.draw.polygon(screen, (r, g, b), vertices)

pygame.draw.circle(screen, (r, g, b), (self.x, self.y), 4*head)

class predator:

speed=10

color=(255,0,255)

def __init__(self, x, y,z, direction):

self.x = x

self.y = y

self.z=z

self.direction = direction

self.direction_vectors=[]

def draw(self, screen):

size_adjust = (self.z / Z)+0.5

if np.linalg.norm(self.direction) != 1.0:

self.direction = self.direction / np.linalg.norm(self.direction)

# Scale the RGB components based on z

r = min(255, max(0, int(predator.color[0] * (1 - self.z / Z))))

g = min(255, max(0, int(predator.color[1] * (1 - self.z / Z))))

b = min(255, max(0, int(predator.color[2] * (1 - self.z / Z))))

pygame.draw.circle(screen, (r,g,b), (self.x, self.y), 6.5/size_adjust)


def update(self):

chance=random.randint(1,10)

if chance==1:

self.direction = rotate_vector(self.direction,30)

elif chance==2:

self.direction = rotate_vector(self.direction,-30)

total_direction = np.sum(self.direction_vectors, axis=0)

if np.linalg.norm(total_direction) > 0:

total_direction = total_direction / np.linalg.norm(total_direction)

if isinstance(total_direction,np.ndarray):

self.direction = total_direction

updated_position = np.array([self.x, self.y, self.z]) + np.array(self.direction) * predator.speed


self.x = updated_position[0]

self.y = updated_position[1]

self.z = updated_position[2]

if thorus==True:

if self.x>X:

self.x=0

if self.y>Y:

self.y=0

if self.z>Z:

self.z=0

if self.x<0:

self.x=X

if self.y<0:

self.y=Y

if self.z<0:

self.z=Z

else:

if self.x>X:

self.direction[0]=-self.direction[0]

if self.y>Y:

self.direction[1]=-self.direction[1]

if self.z>Z:

self.direction[2]=-self.direction[2]

if self.x<0:

self.direction[0]=-self.direction[0]

if self.y<0:

self.direction[1]=-self.direction[1]

if self.z<0:

self.direction[2]=-self.direction[2]
animals = []

distx = random.randint(1, X)

disty = random.randint(1, Y)

distz = random.randint(1, Z)

length = math.sqrt(distx ** 2 + disty ** 2 + distz**2)

for n in range(numb_fish):

distx = random.randint(1, X)

disty = random.randint(1, Y)

distz = random.randint(1, Z)

length = math.sqrt(distx ** 2 + disty ** 2 + distz**2)

animals.append(fish(x=random.randint(1, X,), y=random.randint(1, Y),


z=random.randint(1,Z),direction=np.array([distx / length, disty / length, distz/length])))

for n in range(numb_pred):

distx = random.randint(1, X)

disty = random.randint(1, Y)

distz = random.randint(1, Z)

length = math.sqrt(distx ** 2 + disty ** 2 + distz**2)

animals.append(predator(x=random.randint(1, X), y=random.randint(1, Y),


z=random.randint(1,Z),direction=np.array([distx / length, disty / length, distz/length])))

def fish_update(attraction,repulsion,alignment,half_angle):
coordinates = np.array([[animal.x, animal.y, animal.z] for animal in animals])

distances = cdist(coordinates, coordinates, metric='euclidean')

indices = np.triu_indices(distances.shape[0], k=1)

all_indices = np.vstack((indices[0], indices[1]))

for animal in animals:

animal.direction_vectors = []

for i, j in zip(*all_indices):

if isinstance(animals[i], fish):

if in_vision_field(animals[i], animals[j], half_angle) and (thorus==True) or (thorus==False and


animals[i].x<X-5 and animals[i].y<Y-5 and animals[i].z<Z-5):

if isinstance(animals[j],fish):

#repulsion

if distances[i, j] < repulsion and distances[i, j] >0:

rep = np.array([(animals[i].x - animals[j].x) / (distances[i, j]), (animals[i].y - animals[j].y) /


(distances[i, j]),(animals[i].z - animals[j].z) / (distances[i, j])])

rep = rep / np.linalg.norm(rep)

animals[i].direction_vectors.append(rep)

animals[j].direction_vectors.append(-rep)
#alignement

elif distances[i, j] < alignment:

al = np.array([(animals[i].x + animals[j].x), animals[i].y + animals[j].y, animals[i].z +


animals[j].z])

al = al / np.linalg.norm(al)

animals[i].direction_vectors.append(al)

alj = np.array([(animals[i].x + animals[j].x), animals[i].y + animals[j].y, animals[i].z +


animals[j].z])

alj = alj / np.linalg.norm(alj)

print(np.linalg.norm(alj))

#attraction

elif distances[i, j] <= attraction and distances[i, j] > 0:

attr = np.array([(animals[j].x - animals[i].x) / distances[i, j], (animals[j].y - animals[i].y) /


distances[i, j], (animals[j].z - animals[i].z) / distances[i, j]])

attr = attr / np.linalg.norm(attr)

animals[i].direction_vectors.append(attr)

animals[j].direction_vectors.append(-attr)

elif distances[i, j] < predators_repulsion:

prep = np.array([(animals[i].x - animals[j].x) / (distances[i, j]), (animals[i].y -


animals[j].y) / (distances[i, j]),(animals[i].z - animals[j].z) / (distances[i, j])])

prep = prep / np.linalg.norm(prep)

animals[i].direction_vectors.append(prep)
if isinstance(animals[j],predator) and isinstance(animals[i],fish) and in_vision_field(animals[j],
animals[i], variables['Vision Angle']):

if distances[i, j] < predators_repulsion:

patt = np.array([(animals[i].x - animals[j].x) / (distances[i, j]), (animals[i].y - animals[j].y) /


(distances[i, j]),(animals[i].z - animals[j].z) / (distances[i, j])])

patt = patt / np.linalg.norm(patt)

animals[j].direction_vectors.append(patt)

for animal in animals:

if isinstance(animal,fish):

total_direction = np.sum(animal.direction_vectors, axis=0)

if np.linalg.norm(total_direction) > 0:

total_direction = total_direction / np.linalg.norm(total_direction)

chance=random.randint(1,turn_probability)

if chance==2 and (thorus==True) or (thorus==False and animals[i].x<X-5 and animals[i].y<Y-5


and animals[i].z<Z-5):

total_direction = rotate_vector(animal.direction,29)
elif chance==3 and (thorus==True) or (thorus==False and animals[i].x<X-5 and animals[i].y<Y-5
and animals[i].z<Z-5):

total_direction = rotate_vector(animal.direction,-29)

else:

pass

angle_between = np.arccos(np.dot(animal.direction, total_direction) /


(np.linalg.norm(animal.direction) * np.linalg.norm(total_direction)))

if np.any(angle_between >= threshold_angle):

rotation_axis = np.cross(animal.direction, total_direction)

rotation_axis /= np.linalg.norm(rotation_axis)

rotation_matrix = np.array([[np.cos(threshold_angle) + rotation_axis[0]**2 * (1 -


np.cos(threshold_angle)), rotation_axis[0] * rotation_axis[1] * (1 - np.cos(threshold_angle)) -
rotation_axis[2] * np.sin(threshold_angle), rotation_axis[0] * rotation_axis[2] * (1 -
np.cos(threshold_angle)) + rotation_axis[1] * np.sin(threshold_angle)], [rotation_axis[1] *
rotation_axis[0] * (1 - np.cos(threshold_angle)) + rotation_axis[2] * np.sin(threshold_angle),
np.cos(threshold_angle) + rotation_axis[1]**2 * (1 - np.cos(threshold_angle)), rotation_axis[1] *
rotation_axis[2] * (1 - np.cos(threshold_angle)) - rotation_axis[0] * np.sin(threshold_angle)],
[rotation_axis[2] * rotation_axis[0] * (1 - np.cos(threshold_angle)) - rotation_axis[1] *
np.sin(threshold_angle), rotation_axis[2] * rotation_axis[1] * (1 - np.cos(threshold_angle)) +
rotation_axis[0] * np.sin(threshold_angle), np.cos(threshold_angle) + rotation_axis[2]**2 * (1 -
np.cos(threshold_angle))]])

total_direction = np.dot(rotation_matrix, animal.direction)

if isinstance(total_direction,np.ndarray):

animal.direction = total_direction

updated_position = np.array([animal.x, animal.y, animal.z]) + animal.direction * animal.speed

animal.x = updated_position[0]

animal.y = updated_position[1]

animal.z = updated_position[2]
if thorus==True:

if animal.x>X:

animal.x=0

if animal.y>Y:

animal.y=0

if animal.z>Z:

animal.z=0

if animal.x<0:

animal.x=X

if animal.y<0:

animal.y=Y

if animal.z<0:

animal.z=Z

else:

if animal.x>X:

animal.direction[0]=-animal.direction[0]

animal.x=X

animals[i].direction_vectors.append(np.array([-1,0,0]))

if animal.y>Y:

animal.direction[1]=-animal.direction[1]

animal.y=Y

animals[i].direction_vectors.append(np.array([0,-1,0]))

if animal.z>Z:

animal.direction[2]=-animal.direction[2]

animal.z=Z

animals[i].direction_vectors.append(np.array([0,0,-1]))

if animal.x<0:

animal.direction[0]=-animal.direction[0]

animal.x=0

animals[i].direction_vectors.append(np.array([1,0,0]))
if animal.y<0:

animal.direction[1]=-animal.direction[1]

animal.y=0

animals[i].direction_vectors.append(np.array([0,1,0]))

if animal.z<0:

animal.direction[2]=-animal.direction[2]

animal.z=0

animals[i].direction_vectors.append(np.array([0,0,1]))

else:

animal.update()

for animal in animals:

if isinstance(animal,type(fish)):

animal.direction_vectors = [vec / np.linalg.norm(vec) for vec in animal.direction_vectors]

# Initialize Pygame

pygame.init()

pygame.font.init()

# Font

font = pygame.font.SysFont(None, 30)

# Variables

variables = {

'Vision Angle': 50,

'Repulsion': 50,

'Alignment': 50,

'Attraction': 50

# Set up the screen


screen = pygame.display.set_mode((WIDTH, HEIGHT))

pygame.display.set_caption("animals")

# Colors

WHITE = (255, 255, 255)

BLUE = (0,25,50)

# Set up the clock

clock = pygame.time.Clock()

# Game loop

running = True

while running:

# Handle events

for event in pygame.event.get():

if event.type == pygame.QUIT:

running = False

elif event.type == pygame.MOUSEBUTTONDOWN:

if slider_x <= event.pos[0] <= slider_x + slider_width:

for idx, name in enumerate(variables):

y = 50 + idx * slider_spacing

if y + 30 <= event.pos[1] <= y + 30 + slider_height:

variables[name] = int((event.pos[0] - slider_x) / slider_width * slider_max)

screen.fill(BLUE)

fish_update(variables['Attraction'],variables['Repulsion'],variables['Alignment'],variables['Vision
Angle'])

# Draw sliders
y = 50

for name, value in variables.items():

draw_slider(name, value, y)

y += slider_spacing

for animal in animals:

animal.draw(screen)

# Update the display

pygame.display.flip()

# Cap the frame rate

clock.tick(60)

# Quit Pygame

pygame.quit()

sys.exit()

You might also like