diff options
Diffstat (limited to 'ellipse/main.py')
| -rw-r--r-- | ellipse/main.py | 158 |
1 files changed, 124 insertions, 34 deletions
diff --git a/ellipse/main.py b/ellipse/main.py index 758800f..9e9d831 100644 --- a/ellipse/main.py +++ b/ellipse/main.py @@ -35,8 +35,6 @@ class Ellipse: self.b = b self.c = sqrt(self.a * self.a - self.b * self.b) - # self.f1 = local2screen(self.c, 0) - # self.f2 = local2screen(-self.c, 0) self.f1 = (self.c, 0) self.f2 = (-self.c, 0) @@ -79,7 +77,6 @@ class NiceEllipse: self.lastend = None def draw(self, deltatime, screen, cx, cy): - print(deltatime) for start, end in self.lines: pygame.draw.line(screen, WHITE, start, end, 2) @@ -121,8 +118,6 @@ class NiceEllipse: class ScreenRay: def __init__(self, a: Vector2, b: Vector2, speed: float): - # self.a = a - # self.b = b self.pos = a self.dir = Vector2(b.x - a.x, b.y - a.y) self.dir.normalize_ip() @@ -184,29 +179,11 @@ class EllipseRay: xc = (x0 + x1) / 2 yc = (y0 + y1) / 2 tmp = self.ellipse(xc, yc) - # if abs(tmp) < eps or hypot(x1 - x0, y1 - y0) < eps: - if abs(tmp) < eps: + if abs(tmp) < eps or hypot(x1 - x0, y1 - y0) < eps: return Vector2(xc, yc) elif tmp >= eps: - # print(tmp, (x0, y0), (x1, y1), (xc, yc), (x1 - x0, y1 - y0)) - t1 = self.ellipse(xc, yc) - t2 = self.ellipse(x0, y0) - if t1 > 0 and t2 > 0: - print(">", t1, t2) - - if depth > 20: - print("> ret") - return Vector2(xc, yc) return self.find_point(x0, y0, xc, yc, depth+1) elif tmp <= -eps: - t1 = self.ellipse(xc, yc) - t2 = self.ellipse(x1, y1) - if t1 > 0 and t2 > 0: - print("<", t1, t2) - - if depth > 20: - print("< ret") - return Vector2(xc, yc) return self.find_point(xc, yc, x1, y1, depth+1) def update(self, deltatime): @@ -239,12 +216,16 @@ class EllipseRay: kas = Vector2(p1.x - p0.x, p1.y - p0.y) kas.normalize_ip() - # angle = kas.angle_to(self.dir) - kas_p = Vector2(1, -kas.x / kas.y) - kas_p.normalize_ip() + if kas.y == 0: + normal = Vector2(0, -1) + else: + normal = Vector2(1, -kas.x / kas.y) + + normal.normalize_ip() - self.dir.reflect_ip(kas_p) + + self.dir.reflect_ip(normal) ######################## @@ -276,6 +257,13 @@ class LaserEllipse: return (x * x) / (self.a * self.a) + (y * y) / (self.b * self.b) - 1 def get_normal(self, p0): + if p0.y == 0: + if p0.x < 0: + normal = Vector2(-1, 0) + else: + normal = Vector2(1, 0) + return normal + m = 1 n = -(p0.x * self.b * self.b) / (p0.y * self.a * self.a) p1 = Vector2(p0.x + m, p0.y + n) @@ -283,7 +271,10 @@ class LaserEllipse: kas = Vector2(p1.x - p0.x, p1.y - p0.y) kas.normalize_ip() - normal = Vector2(1, -kas.x / kas.y) + if kas.y == 0: + normal = Vector2(0, -1) + else: + normal = Vector2(1, -kas.x / kas.y) return normal.normalize() def find_point(self, x0, y0, x1, y1, depth=0): @@ -318,8 +309,14 @@ class LaserEllipse: end = self.find_point(start.x, start.y, tmp.x, tmp.y) return end - def update(self, deltatime): - self.ray_t += deltatime / 10 + def update(self, deltatime, value): + # self.ray_t += deltatime / 10 + self.ray_t = value * 2 * pi + + def set_ray_end(self, mousepos): + pos = screen2local(*mousepos) + if pygame.mouse.get_pressed()[0] and self.ellipse(*pos) < 0: + self.ray_end = Vector2(*pos) def draw(self, deltatime, screen, cx, cy): self.draw_lasers(screen) @@ -348,8 +345,87 @@ class LaserEllipse: end = local2screen(ray_start + d) pygame.draw.line(screen, WHITE, start, end, 2) + pygame.draw.circle(screen, GREEN, local2screen(self.ray_end), 2) +class GUISlider: + def __init__(self, rect: Rect, value=0): + self.rect = rect + + self.filled_fg = Color("#2ef6a8") + self.filled_bg = Color("#25cc8c") + + self.empty_fg = Color("#8a8a8a") + self.empty_bg = Color("#737373") + + self.value = value + + def update(self, mousepos): + if not self.rect.collidepoint(mousepos) or \ + not pygame.mouse.get_pressed()[0]: + return + + radius = self.rect.h / 2 + self.value = (mousepos[0] - self.rect.left - radius) / (self.rect.width - radius * 2) + if self.value > 1: + self.value = 1 + elif self.value < 0: + self.value = 0 + + def draw(self, screen): + padding = 3 + r = self.rect.height // 2 + + # Empty background + x = self.rect.left + r + y = self.rect.top + r + pygame.draw.circle(screen, self.empty_bg, (x, y), r) + + x = self.rect.right - r + pygame.draw.circle(screen, self.empty_bg, (x, y), r) + + lt = (self.rect.left + r, self.rect.top) + wh = (self.rect.w - 2 * r, self.rect.h) + pygame.draw.rect(screen, self.empty_bg, Rect(lt, wh)) + + # Empty foreground + x = self.rect.left + r + y = self.rect.top + r + pygame.draw.circle(screen, self.empty_fg, (x, y), r - padding) + + x = self.rect.right - r + pygame.draw.circle(screen, self.empty_fg, (x, y), r - padding) + + lt = (self.rect.left + r, self.rect.top + padding) + wh = (self.rect.w - 2 * r, self.rect.h - padding * 2) + pygame.draw.rect(screen, self.empty_fg, Rect(lt, wh)) + + # Filled background + x = self.rect.left + r + y = self.rect.top + r + pygame.draw.circle(screen, self.filled_bg, (x, y), r) + + lt = (self.rect.left + r, self.rect.top) + wh = ((self.rect.w - 2 * r) * self.value, self.rect.h) + pygame.draw.rect(screen, self.filled_bg, Rect(lt, wh)) + + # Filled foreground + x = self.rect.left + r + y = self.rect.top + r + pygame.draw.circle(screen, self.filled_fg, (x, y), r - padding) + + lt = (self.rect.left + r, self.rect.top + padding) + wh = ((self.rect.w - 2 * r) * self.value, self.rect.h - padding * 2) + pygame.draw.rect(screen, self.filled_fg, Rect(lt, wh)) + + # Circle + x = self.rect.left + r + (self.rect.w - 2 * r) * self.value + y = self.rect.top + r + pygame.draw.circle(screen, WHITE, (x, y), r + padding) + pygame.draw.circle(screen, Color("#e7e7e7"), (x, y), r - 4) + + + pygame.init() WIDTH, HEIGHT = SIZE = 800, 600 @@ -364,6 +440,10 @@ WHITE = Color("white") GREEN = Color("green") RED = Color("red") + +font = pygame.font.SysFont("courier", 20) +slider = GUISlider(Rect(10, HEIGHT - 30, WIDTH - 120, 20)) +k = 2 * pi el = LaserEllipse(300, 200, ray_t=200, ray_end=Vector2(0, 100)) rays = [] @@ -375,7 +455,6 @@ rays = [] # r = EllipseRay(Vector2(x0, y0), Vector2(xr, yr), 70, el) # rays.append(r) -# deltatime = pygame.time.get_ticks() while running: screen.fill(BLACK) @@ -386,7 +465,16 @@ while running: r.update(deltatime) r.draw(screen) el.draw(deltatime, screen, 0, 0) - el.update(deltatime) + el.update(deltatime, slider.value) + + slider.draw(screen) + text = font.render(f"t = {round(slider.value * k, 2)}", True, WHITE) + rect = Rect(0, 0, 0, 0) + rect.left = WIDTH - 105 + rect.w = text.get_rect().w + rect.h = text.get_rect().h + rect.centery = HEIGHT - 20 + screen.blit(text, rect) # ... @@ -400,6 +488,8 @@ while running: if event.key == K_ESCAPE: pygame.quit() exit() + elif event.type in [MOUSEMOTION, MOUSEBUTTONDOWN]: + slider.update(event.pos) + el.set_ray_end(event.pos) clock.tick(60) - # deltatime = pygame.time.get_ticks() - deltatime # print(clock.get_fps()) |