summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ellipse/main.py158
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())