Info_edupage/UI/Objects/nr_objects/light_objects/LuminousCircleEffect.py
2021-09-13 20:03:31 +02:00

83 lines
3.0 KiB
Python

import math
import random
import numpy as np
from numpy import array
from pygame.draw import circle
class LuminousCircleEffect:
object_type = "nr_l"
def __init__(self, position, r, color, scene, circles_n=20, point_speed=0.02, movement_stability=5):
self.position = position
self.r = r
self.color = color
self.scene = scene
self.circles_n = circles_n
self.point_speed = point_speed
self.point_speed_inverse = 1 / self.point_speed
self.movement_stability = movement_stability
self.point_position = array([0., 0.])
self.point_velocity = array([0., 0.])
def update(self):
self.point_position += self.point_velocity
a = math.sqrt(sum(self.point_position ** 2))
if a > 1:
self.point_position /= a
a = 1
b = 1 - a
c = (0.5 * a) + b
d = math.sqrt((c ** 2) - ((a * 0.5) ** 2))
if a == 0:
rotation_point = complex(1, 0)
else:
normalized_point_position = self.point_position / a
rotation_point = complex(*normalized_point_position)
delta = random.uniform(0, math.tau)
m = max(random.uniform(0, 1), random.uniform(0, 1))
point_position = complex(math.cos(delta) * m * c, math.sin(delta) * m * d) * rotation_point
point_position = array([point_position.real, point_position.imag])
self.point_velocity *= self.movement_stability * self.point_speed_inverse
self.point_velocity += point_position - self.point_position
self.point_velocity /= math.sqrt(sum(self.point_velocity ** 2))
self.point_velocity *= self.point_speed
def blit(self, light_blit=False):
if light_blit:
s, transformed_position = self.scene.get_info_for_light_objects(self.position)
rescaled_r = self.r * self.scene.pd_
x = np.linspace(0, self.point_position[0], self.circles_n) * rescaled_r
y = np.linspace(0, self.point_position[1], self.circles_n) * rescaled_r
r = np.linspace(rescaled_r, 0, self.circles_n)
c = [np.linspace(value, 255, self.circles_n) for value in self.color]
for i in range(self.circles_n - 1):
circle(s, (c[0][i], c[1][i], c[2][i]),
transformed_position + array([x[i], y[i]]), r[i])
else:
rescaled_r = self.r * self.scene.pd_
transformed_position = self.scene.matrix @ self.position
x = np.linspace(0, self.point_position[0], self.circles_n) * rescaled_r
y = np.linspace(0, self.point_position[1], self.circles_n) * rescaled_r
r = np.linspace(rescaled_r, 0, self.circles_n)
c = [np.linspace(value, 255, self.circles_n) for value in self.color]
for i in range(self.circles_n - 1):
circle(self.scene.s, (c[0][i], c[1][i], c[2][i]),
transformed_position + array([x[i], y[i]]), r[i])