diff --git a/__pycache__/particle.cpython-312.pyc b/__pycache__/particle.cpython-312.pyc index 25b743f..077ed3f 100644 Binary files a/__pycache__/particle.cpython-312.pyc and b/__pycache__/particle.cpython-312.pyc differ diff --git a/__pycache__/sensor.cpython-312.pyc b/__pycache__/sensor.cpython-312.pyc new file mode 100644 index 0000000..ba68a55 Binary files /dev/null and b/__pycache__/sensor.cpython-312.pyc differ diff --git a/__pycache__/slider.cpython-312.pyc b/__pycache__/slider.cpython-312.pyc new file mode 100644 index 0000000..ca00cce Binary files /dev/null and b/__pycache__/slider.cpython-312.pyc differ diff --git a/main.py b/main.py index 1624859..3c20a5d 100644 --- a/main.py +++ b/main.py @@ -3,19 +3,23 @@ import numpy as np import matplotlib.pyplot as plt from particle import Particle from sensor import Sensor +from slider import Slider pygame.init() SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 +SENSOR_DISTANCE = 200 + +y_lim = 40000 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) -sensor = Sensor(width = 50, distance = 200, space = 200) +sensor = Sensor(width = 50, distance = SENSOR_DISTANCE, space = 300) -silica = Particle(speed = 1, size = 20, perm = 4) +silica = Particle(speed = 1, size = 60, perm = 4) time = .1 time_data = [] @@ -26,13 +30,13 @@ volume_data = [] plt.ion() fig, ax = plt.subplots() line, = ax.plot([], [], 'r-') -ax.set_xlim(0, 400) -ax.set_ylim(0, 40000) +ax.set_xlim(0, 800) +ax.set_ylim(-1000, y_lim) ax.set_xlabel('Time (s)') ax.set_ylabel('Volume') ax.set_title('Volume/time') - +slider1 = Slider(20, 20, 100, 20, 20, SENSOR_DISTANCE / 2, 80) run = True while run: @@ -49,12 +53,22 @@ while run: sensor.generate(SCREEN_WIDTH, SCREEN_HEIGHT, screen) pygame.draw.circle(screen, (255, 255, 255), (distance - silica.size, 300), silica.size) + pygame.draw.circle(screen, (0,255,0), (distance - silica.size, 300), 10) + + slider1.draw(screen) + + silica.updateSize(slider1.value) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False + slider1.handle_event(event) - volume = sensor.testSensor1(distance, silica) + volume = sensor.getParticleVolume(distance, silica) + + if (volume > y_lim): + y_lim = volume + (volume * 1.2) + ax.set_ylim(-1000, y_lim) time_data.append(time) volume_data.append(volume) @@ -69,10 +83,6 @@ while run: pygame.display.update() time = time + 1 - - print(volume) - - pygame.quit() diff --git a/particle.py b/particle.py index 7162884..6977c62 100644 --- a/particle.py +++ b/particle.py @@ -15,4 +15,8 @@ class Particle: partialVol = (1/3) * math.pi * height * height * ((3 * self.size) - height) return partialVol + def updateSize(self, size): + self.size = size + self.volume = (4/3) * math.pi * size * size * size + diff --git a/sensor.py b/sensor.py index 61ce981..d30499a 100644 --- a/sensor.py +++ b/sensor.py @@ -7,7 +7,7 @@ class Sensor: self.space = space def generate(self, screenWidth, screenHeight, screen): - self.sensor1_x = (screenWidth / 2) - (self.space / 2) + self.sensor1_x = (screenWidth / 2) - (self.space / 2) - self.width self.sensor1_y = 0 self.sensor1_x_size = self.width self.sensor1_y_size = (screenHeight / 2) - (self.distance / 2) @@ -20,15 +20,85 @@ class Sensor: pygame.draw.rect(screen, (0, 0, 255), sensor1a) pygame.draw.rect(screen, (0, 0, 255), sensor1b) + self.sensor2_x = (screenWidth / 2) + (self.space / 2) + self.sensor2_y = 0 + self.sensor2_x_size = self.width + self.sensor2_y_size = (screenHeight / 2) - (self.distance / 2) + + self.inner2 = self.sensor2_x + self.outer2 = self.inner2 + self.width + + sensor2a = pygame.Rect(self.sensor2_x, self.sensor2_y, self.sensor2_x_size, self.sensor2_y_size) + sensor2b = pygame.Rect(self.sensor2_x, self.sensor2_y + self.sensor2_y_size + self.distance, self.sensor2_x_size, self.sensor2_y_size) + pygame.draw.rect(screen, (0, 0, 255), sensor2a) + pygame.draw.rect(screen, (0, 0, 255), sensor2b) + def testSensor1(self, partCenter, particle): - if particle.size >= abs(self.inner1 - (partCenter - particle.size)): - volume = particle.partialVol(particle.size - (self.inner1 - (partCenter - particle.size))) + + particle_x = partCenter - particle.size + particle_right = particle_x + particle.size + particle_left = particle_x - particle.size + # Sensor lines on one half of sphere center + if particle_right > self.outer1 and particle_x < self.inner1: + volume = particle.partialVol(self.width + (particle_right - self.outer1)) - particle.partialVol(particle_right - self.outer1) + print("On right half") + print(volume) return volume - elif particle.size >= abs(self.outer1 - (partCenter - particle.size)): - volume = particle.volume - particle.partialVol(particle.size - (self.outer1 - (partCenter - particle.size))) + # if Sensor is on left half of sphere center + elif particle_left < self.inner1 and particle_x > self.outer1: + volume = particle.partialVol(self.width + (self.inner1 - particle_left)) - particle.partialVol(self.inner1 - particle_left) + print("On left half") + print(volume) return volume - elif ((partCenter - particle.size) >= self.inner1 and (partCenter - particle.size) <= self.outer1): + # On bolth halves + elif (particle_x >= self.inner1 and particle_x <= self.outer1) and particle_left < self.inner1 and particle_right > self.outer1: + volume_left = particle.partialVol(self.inner1 - particle_left) + volume_right = particle.partialVol(particle_right - self.outer1) + volume = particle.volume - (volume_left + volume_right) + print("On both halves") + print(volume_left) + print(volume_right) + return volume + elif (particle_right > self.inner1 and particle_right < self.outer1) and particle_x <= self.inner1: + volume = particle.partialVol(particle_right - self.inner1) + print("Approaching from left") + print(volume) + return volume + elif (particle_left > self.inner1 and particle_left < self.outer1) and particle_x >= self.outer1: + volume = particle.partialVol(self.outer1 - particle_left) + print("Leaving from left") + print(volume) + return volume + elif (particle_right > self.inner1 and particle_right <= self.outer1) and (particle_left >= self.inner1 and particle_left < self.outer1): + print("in between") + print(particle.volume) + return particle.volume + else: + return 0 + + def testSensor2(self, partCenter, particle): + if (particle.size >= abs(self.inner2 - (partCenter - particle.size))) and (particle.size >= abs(self.outer2 - (partCenter - particle.size))): + volume = ((particle.volume / 2) - (particle.partialVol(particle.size - ((partCenter - particle.size) - self.inner2)))) + ((particle.volume / 2) - particle.partialVol(particle.size - (self.outer2 - (partCenter - particle.size)))) + return volume + elif particle.size >= abs(self.inner2 - (partCenter - particle.size)): + volume = particle.partialVol(particle.size - (self.inner2 - (partCenter - particle.size))) + return volume + elif particle.size >= abs(self.outer2 - (partCenter - particle.size)): + volume = particle.volume - particle.partialVol(particle.size - (self.outer2 - (partCenter - particle.size))) + return volume + elif ((partCenter - particle.size) >= self.inner2 and (partCenter - particle.size) <= self.outer2): volume = particle.volume return volume else: - return 0 \ No newline at end of file + return 0 + + def getParticleVolume(self, partCenter, particle): + volume1 = self.testSensor1(partCenter, particle) + volume2 = self.testSensor2(partCenter, particle) + + if volume1: + return volume1 + elif volume2: + return volume2 + else: + return 0 diff --git a/slider.py b/slider.py new file mode 100644 index 0000000..304e27d --- /dev/null +++ b/slider.py @@ -0,0 +1,35 @@ +import pygame + +WHITE = (255, 255, 255) +GRAY = (200, 200, 200) +BLACK = (0, 0, 0) +RED = (255, 0, 0) + +class Slider: + + def __init__(self, x, y, w, h, min_val, max_val, initial_val): + self.rect = pygame.Rect(x, y, w, h) + self.min_val = min_val + self.max_val = max_val + self.value = initial_val + self.grabbed = False + + def draw(self, screen): + # Draw the background + pygame.draw.rect(screen, GRAY, self.rect) + # Draw the handle (circle) + handle_x = self.rect.x + (self.value - self.min_val) / (self.max_val - self.min_val) * self.rect.width + pygame.draw.circle(screen, RED, (int(handle_x), self.rect.centery), self.rect.height // 2) + + def handle_event(self, event): + if event.type == pygame.MOUSEBUTTONDOWN: + if self.rect.collidepoint(event.pos): + self.grabbed = True + elif event.type == pygame.MOUSEBUTTONUP: + self.grabbed = False + elif event.type == pygame.MOUSEMOTION: + if self.grabbed: + mouse_x = event.pos[0] + # Constrain the handle within the slider + new_value = (mouse_x - self.rect.x) / self.rect.width * (self.max_val - self.min_val) + self.min_val + self.value = max(self.min_val, min(self.max_val, new_value))