-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsource.py
More file actions
79 lines (63 loc) · 2.12 KB
/
Copy pathsource.py
File metadata and controls
79 lines (63 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import numpy as np
import pygame
class PhaseSource:
def __init__(
self,
center,
y_offset=0,
R=1.0,
L=2,
amplitude=5.0,
frequency=1.0,
phase_shift=0.0,
scale=1.0
):
# position for drawing
self.center = (center[0], center[1] + y_offset)
# electrical parameters
self.R = R
self.L = L
self.amplitude = amplitude
self.frequency = frequency
self.phase_shift = phase_shift
self.phase=self.phase_shift
self.scale = scale
self.line_width = max(2, int(12 * scale))
self.circle_radius = max(4, int(6 * scale))
# dynamic variables
self.current = 0.0
self.charge = 0.0
# -------------------------
# voltage input
# -------------------------
def voltage(self):
return self.amplitude * np.sin(self.phase)
# -------------------------
# update system
# -------------------------
def update(self, dt):
# integrate phase
self.phase += 2 * np.pi * self.frequency * dt
# compute voltage from phase
V = self.amplitude * np.sin(self.phase)
L_safe = max(self.L, 1e-6)
dI_dt = (V - self.R * self.current) / L_safe
self.current += dI_dt * dt
self.charge += self.current * dt
return self.current
# -------------------------
# draw cable
# -------------------------
def draw(self, screen):
cx, cy = self.center
start = (int(cx), int(cy))
end = (screen.get_width(), int(cy))
# color based on current
intensity =0* min(1.0, abs(self.current) / self.amplitude)
if self.current >= 0:
color = (int(255 * intensity), 0,0)
else:
color = (0,0, int(255 * intensity))
pygame.draw.line(screen, (30, 30, 30), start, end, self.line_width)
pygame.draw.line(screen, color, start, end, max(2, int(8 * self.scale)))
pygame.draw.circle(screen, (200, 200, 200), end, self.circle_radius)