Elementary computational geometry
(Различия между версиями)
Gusarev (обсуждение | вклад) |
Gusarev (обсуждение | вклад) |
||
Строка 137: | Строка 137: | ||
[https://prog.school.ioffe.ru/geometry_course/2020-10-07/photo_2.jpg Фото с доски: расстояние от точки до луча] | [https://prog.school.ioffe.ru/geometry_course/2020-10-07/photo_2.jpg Фото с доски: расстояние от точки до луча] | ||
+ | |||
+ | <source lang="python"> | ||
+ | from math import atan, pi | ||
+ | |||
+ | |||
+ | class Point: | ||
+ | |||
+ | # конструктор | ||
+ | def __init__(self, *args): | ||
+ | if len(args) == 1 and type(args[0]) == str: | ||
+ | self.x, self.y = map(int, args[0].split()) | ||
+ | elif len(args) == 2 and type(args[0]) == int and type(args[1]) == int: | ||
+ | self.x = int(args[0]) | ||
+ | self.y = int(args[1]) | ||
+ | else: | ||
+ | raise Exception("Неверно указан тип параметров при создании точки!") | ||
+ | |||
+ | |||
+ | def __str__(self): | ||
+ | return "({0}, {1})".format(self.x, self.y) | ||
+ | |||
+ | |||
+ | class Vector: | ||
+ | |||
+ | # конструктор | ||
+ | def __init__(self, a, b): | ||
+ | if type(a) == Point and type(b) == Point: | ||
+ | self.x = b.x - a.x | ||
+ | self.y = b.y - a.y | ||
+ | elif type(a) == int and type(b) == int: | ||
+ | self.x = a | ||
+ | self.y = b | ||
+ | else: | ||
+ | raise Exception("Неверно указан тип параметра при создании вектора!") | ||
+ | |||
+ | def __str__(self): | ||
+ | return "({0}, {1})".format(self.x, self.y) | ||
+ | |||
+ | def __add__(self, other): | ||
+ | return Vector(self.x + other.x, self.y + other.y) | ||
+ | |||
+ | def scalar(self, other): | ||
+ | return self.x * other.x + self.y * other.y | ||
+ | |||
+ | def cross(self, other): | ||
+ | return self.x * other.y - self.y * other.x | ||
+ | |||
+ | def polar(self): | ||
+ | one = Vector(1, 0) | ||
+ | sc = one.scalar(self) | ||
+ | cr = one.cross(self) | ||
+ | add = 0 | ||
+ | if cr < 0: | ||
+ | add = pi | ||
+ | if sc == 0: | ||
+ | return pi / 2 + add | ||
+ | if cr == 0: | ||
+ | if sc > 0: | ||
+ | return 0 | ||
+ | else: | ||
+ | return pi | ||
+ | if sc > 0 and cr > 0: | ||
+ | return atan(cr / sc) | ||
+ | if sc > 0 and cr < 0: | ||
+ | return atan(cr / sc) + 2 * pi | ||
+ | if sc < 0: | ||
+ | return atan(cr / sc) + pi | ||
+ | |||
+ | def angle(self, other): | ||
+ | ans = abs(self.polar() - other.polar()) | ||
+ | return ans if ans < pi else 2 * pi - ans | ||
+ | |||
+ | class Ray: | ||
+ | |||
+ | # конструктор | ||
+ | def __init__(self, A, B): | ||
+ | self.start = A | ||
+ | self.direction = Vector(A, B) | ||
+ | |||
+ | def pt_in(self, A): | ||
+ | # реализуйте сами, мы её обсудили на занятии | ||
+ | pass | ||
+ | |||
+ | def dist(A, B): | ||
+ | return ((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y)) ** 0.5 | ||
+ | |||
+ | def pts_same_line(A, B, C): | ||
+ | return Vector(A, B).cross(Vector(A, C)) == 0 | ||
+ | |||
+ | |||
+ | A = Point(*map(int, input().split())) | ||
+ | B = Point(*map(int, input().split())) | ||
+ | C = Point(*map(int, input().split())) | ||
+ | r = Ray(B, C) | ||
+ | |||
+ | |||
+ | if r.pt_in(A): | ||
+ | print('YES') | ||
+ | else: | ||
+ | print('NO') | ||
+ | </source> |
Версия 22:32, 7 октября 2020
Почитать
Сдать тренировочные задачи
Cейчас на сервере есть возможность сдавать задачи на Python 3, C++ 17 и Java 8.
Условия задач | Ссылка для входа | Тесты для самостоятельного тестирования |
---|---|---|
Разные задачи на геометрические примитивы | Вход в тестирующую систему (контест 341) | Все задачи |
Материалы некоторых занятий
Начало — классы Point, Vector (16 сентября 2020 г.)
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "({0}, {1})".format(self.x, self.y)
class Vector:
# конструктор
def __init__(self, a, b):
if type(a) == Point and type(b) == Point:
self.x = b.x - a.x
self.y = b.y - a.y
elif type(a) == int and type(b) == int:
self.x = a
self.y = b
else:
raise Exception("Неверно указан тип параметра при создании вектора!")
def __str__(self):
return "({0}, {1})".format(self.x, self.y)
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def scalar(self, other):
return self.x * other.x + self.y * other.y
P = Vector(3, 4)
Q = Vector(1, 2)
print(P, Q, P + Q)
A = Point(3, 4)
B = Point(1, 2)
v = Vector(1, 3)
u = Vector(-1273548172564, 1)
print(v.scalar(u))
Скалярное и векторное (косое) произведение векторов, неправильная реализация метода Vector.polar() (23 сентября 2020 г.)
from math import atan, pi
class Point:
# конструктор
def __init__(self, *args):
if len(args) == 1 and type(args[0]) == str:
self.x, self.y = map(int, args[0].split())
elif len(args) == 2 and type(args[0]) == int and type(args[1]) == int:
self.x = int(args[0])
self.y = int(args[1])
else:
raise Exception("Неверно указан тип параметров при создании точки!")
def __str__(self):
return "({0}, {1})".format(self.x, self.y)
class Vector:
# конструктор
def __init__(self, a, b):
if type(a) == Point and type(b) == Point:
self.x = b.x - a.x
self.y = b.y - a.y
elif type(a) == int and type(b) == int:
self.x = a
self.y = b
else:
raise Exception("Неверно указан тип параметра при создании вектора!")
def __str__(self):
return "({0}, {1})".format(self.x, self.y)
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def scalar(self, other):
return self.x * other.x + self.y * other.y
def cross(self, other):
return self.x * other.y - self.y * other.x
def polar(self):
one = Vector(1, 0)
return one.cross(self) / one.scalar(self)
def dist(A, B):
return ((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y)) ** 0.5
A = Vector(*map(int, input().split()))
print(A.polar())
Разбор задачи про вычисление полярного угла точки (30.09.2020)
Фото с доски: использование знаков скалярного и косого произведений
Разбор задач про принадлженость точки лучу и расстояние от точки до лучв (07.10.2020)
Фото с доски: принадлежность точки лучу
Фото с доски: расстояние от точки до луча
from math import atan, pi
class Point:
# конструктор
def __init__(self, *args):
if len(args) == 1 and type(args[0]) == str:
self.x, self.y = map(int, args[0].split())
elif len(args) == 2 and type(args[0]) == int and type(args[1]) == int:
self.x = int(args[0])
self.y = int(args[1])
else:
raise Exception("Неверно указан тип параметров при создании точки!")
def __str__(self):
return "({0}, {1})".format(self.x, self.y)
class Vector:
# конструктор
def __init__(self, a, b):
if type(a) == Point and type(b) == Point:
self.x = b.x - a.x
self.y = b.y - a.y
elif type(a) == int and type(b) == int:
self.x = a
self.y = b
else:
raise Exception("Неверно указан тип параметра при создании вектора!")
def __str__(self):
return "({0}, {1})".format(self.x, self.y)
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def scalar(self, other):
return self.x * other.x + self.y * other.y
def cross(self, other):
return self.x * other.y - self.y * other.x
def polar(self):
one = Vector(1, 0)
sc = one.scalar(self)
cr = one.cross(self)
add = 0
if cr < 0:
add = pi
if sc == 0:
return pi / 2 + add
if cr == 0:
if sc > 0:
return 0
else:
return pi
if sc > 0 and cr > 0:
return atan(cr / sc)
if sc > 0 and cr < 0:
return atan(cr / sc) + 2 * pi
if sc < 0:
return atan(cr / sc) + pi
def angle(self, other):
ans = abs(self.polar() - other.polar())
return ans if ans < pi else 2 * pi - ans
class Ray:
# конструктор
def __init__(self, A, B):
self.start = A
self.direction = Vector(A, B)
def pt_in(self, A):
# реализуйте сами, мы её обсудили на занятии
pass
def dist(A, B):
return ((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y)) ** 0.5
def pts_same_line(A, B, C):
return Vector(A, B).cross(Vector(A, C)) == 0
A = Point(*map(int, input().split()))
B = Point(*map(int, input().split()))
C = Point(*map(int, input().split()))
r = Ray(B, C)
if r.pt_in(A):
print('YES')
else:
print('NO')