summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew <saintruler@gmail.com>2021-04-10 00:41:01 +0400
committerAndrew <saintruler@gmail.com>2021-04-10 00:41:01 +0400
commitffe4cbeb66522b83375cc92f3cd7cd254f88a5f4 (patch)
treed172f23561f16aa1578b2e77b918b8811febf19f
parent95d8ed3af9f069620896d65ad24f64770611ffb1 (diff)
Added ellipse main file
-rw-r--r--ellipse/main.py286
1 files changed, 286 insertions, 0 deletions
diff --git a/ellipse/main.py b/ellipse/main.py
new file mode 100644
index 0000000..93af34e
--- /dev/null
+++ b/ellipse/main.py
@@ -0,0 +1,286 @@
+from pygame.locals import *
+import pygame
+from pygame.math import Vector2
+
+import math
+from math import sin, cos, pi, sqrt
+import time
+
+
+def screen2local(x, y):
+ nx = x - WIDTH / 2
+ ny = HEIGHT / 2 - y
+ return (nx, ny)
+
+
+def local2screen(x, y):
+ nx = x + WIDTH / 2
+ ny = HEIGHT / 2 - y
+ return (nx, ny)
+
+
+class Ellipse:
+ def __init__(self, a, b):
+ self.a = a
+ 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)
+
+ def draw(self, deltatime, screen, cx, cy):
+ cnt = 0
+ for i in range(0, int(2 * pi * 100) + 1):
+ cnt += 1
+ t = i / 100
+ t1 = t + 1 / 100
+
+ # Координаты в локальном пространстве
+ x = self.a * cos(t)
+ y = self.b * sin(t)
+ x1 = self.a * cos(t1)
+ y1 = self.b * sin(t1)
+
+ start = local2screen(x, y)
+ end = local2screen(x1, y1)
+
+ pygame.draw.line(screen, WHITE, start, end, 2)
+
+ pygame.draw.circle(screen, WHITE, local2screen(*self.f1), 3)
+ pygame.draw.circle(screen, WHITE, local2screen(*self.f2), 3)
+
+
+class NiceEllipse:
+ def __init__(self, a, b):
+ self.a = a
+ self.b = b
+
+ self.time = 0
+ self.timeout = 700
+ self.i = 0
+ self.lines = []
+
+ self.c = sqrt(self.a * self.a - self.b * self.b)
+ self.f1 = local2screen(self.c, 0)
+ self.f2 = local2screen(-self.c, 0)
+
+ 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)
+
+ pygame.draw.circle(screen, WHITE, self.f1, 3)
+ pygame.draw.circle(screen, WHITE, self.f2, 3)
+
+ if self.lastend is not None:
+ pygame.draw.line(screen, RED, self.f1, self.lastend, 2)
+ pygame.draw.line(screen, GREEN, self.f2, self.lastend, 2)
+
+ if self.i >= int(2 * pi * 100) + 1:
+ self.lastend = None
+ return
+
+ if self.time > 0:
+ self.time -= deltatime
+ return
+
+ self.time = self.timeout
+
+ t = self.i / 100
+ t1 = t + 1 / 100
+ self.i += 1
+
+ # Координаты в локальном пространстве
+ x = self.a * cos(t)
+ y = self.b * sin(t)
+ x1 = self.a * cos(t1)
+ y1 = self.b * sin(t1)
+
+ start = local2screen(x, y)
+ end = local2screen(x1, y1)
+ self.lastend = end
+
+ self.lines.append((start, end))
+
+ pygame.draw.line(screen, WHITE, start, end, 2)
+
+
+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()
+ self.speed = speed
+
+ def update(self, deltatime):
+ n_pos = self.pos + self.dir * (deltatime * self.speed)
+
+ scr = Vector2(*local2screen(*tuple(self.pos)))
+ scr_npos = Vector2(*local2screen(*tuple(n_pos)))
+
+ if scr_npos.x < 0:
+ self.dir = Vector2(-self.dir.x, self.dir.y)
+ n_pos = Vector2(*screen2local(0, scr.y))
+ elif scr_npos.x > WIDTH:
+ self.dir = Vector2(-self.dir.x, self.dir.y)
+ n_pos = Vector2(*screen2local(WIDTH, scr.y))
+ elif scr_npos.y < 0:
+ self.dir = Vector2(self.dir.x, -self.dir.y)
+ n_pos = Vector2(*screen2local(scr.x, 0))
+ elif scr_npos.y > HEIGHT:
+ self.dir = Vector2(self.dir.x, -self.dir.y)
+ n_pos = Vector2(*screen2local(scr.x, HEIGHT))
+
+ self.pos = n_pos
+
+
+class EllipseRay:
+ def __init__(self, s: Vector2, e: Vector2, speed: float, el):
+ self.a = el.a
+ self.b = el.b
+ self.pos = e
+ self.dir = Vector2(e.x - s.x, e.y - s.y)
+ self.dir.normalize_ip()
+ self.speed = speed
+
+ def eps(self, x, y):
+ a = self.a
+ b = self.b
+ tmp = (x * x) / (a * a) + (y * y) / (b * b)
+ e = 0.05
+ return tmp < 1 + e and tmp > 1 - e
+
+ def update(self, deltatime):
+ npos = self.pos + self.dir * (deltatime * self.speed)
+
+ scr = Vector2(*local2screen(*tuple(self.pos)))
+ scr_npos = Vector2(*local2screen(*tuple(npos)))
+
+ p0 = self.pos
+
+ ########################
+ # Отражение от эллипса #
+ ########################
+
+ if p0.y == 0:
+ if p0.x < 0:
+ self.dir.reflect_ip(Vector2(-1, 0))
+ else:
+ self.dir.reflect_ip(Vector2(1, 0))
+ else:
+ t = 1
+ m = 1
+ n = -(p0.x * self.b * self.b) / (p0.y * self.a * self.a)
+ p1 = Vector2(p0.x + m * t, p0.y + n * t)
+
+ 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 self.eps(npos.x, npos.y):
+ self.dir.reflect_ip(kas_p)
+
+ ########################
+
+ self.pos = npos
+
+
+ def draw(self, screen):
+ loc = tuple(self.pos)
+ scr = local2screen(*loc)
+ pygame.draw.circle(screen, RED, scr, 3)
+
+
+
+class Ray1Ellipse:
+ def __init__(self, a, b):
+ self.a = a
+ self.b = b
+
+ def draw(self, deltatime, screen, cx, cy):
+ cnt = 0
+ for i in range(0, int(2 * pi * 100) + 1):
+ cnt += 1
+ t = i / 100
+ t1 = t + 1 / 100
+
+ # Координаты в локальном пространстве
+ x = self.a * cos(t)
+ y = self.b * sin(t)
+ x1 = self.a * cos(t1)
+ y1 = self.b * sin(t1)
+
+ start = local2screen(x, y)
+ end = local2screen(x1, y1)
+
+ pygame.draw.line(screen, WHITE, start, end, 2)
+
+ c = sqrt(self.a * self.a - self.b * self.b)
+ f1 = local2screen(c, 0)
+ f2 = local2screen(-c, 0)
+
+ pygame.draw.circle(screen, WHITE, f1, 3)
+ pygame.draw.circle(screen, WHITE, f2, 3)
+
+
+pygame.init()
+
+WIDTH, HEIGHT = SIZE = 800, 600
+
+screen = pygame.display.set_mode(SIZE)
+
+clock = pygame.time.Clock()
+running = True
+
+BLACK = Color("black")
+WHITE = Color("white")
+GREEN = Color("green")
+RED = Color("red")
+
+el = Ellipse(300, 200)
+
+rays = []
+nn = 10
+for i in range(1, nn + 1):
+ x0, y0 = el.f2
+ xr = cos(2 * pi * i / nn) + x0
+ yr = sin(2 * pi * i / nn) + y0
+ r = EllipseRay(Vector2(x0, y0), Vector2(xr, yr), 70, el)
+ rays.append(r)
+
+# deltatime = pygame.time.get_ticks()
+
+while running:
+ screen.fill(BLACK)
+
+ deltatime = clock.get_time() / 1000
+
+ for r in rays:
+ r.update(deltatime)
+ r.draw(screen)
+ el.draw(deltatime, screen, 0, 0)
+
+ # ...
+
+ pygame.display.flip()
+
+ for event in pygame.event.get():
+ if event.type == QUIT:
+ pygame.quit()
+ exit()
+ elif event.type == KEYDOWN:
+ if event.key == K_ESCAPE:
+ pygame.quit()
+ exit()
+ clock.tick(60)
+ # deltatime = pygame.time.get_ticks() - deltatime
+ # print(clock.get_fps())