Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2020
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.91 KB | None | 0 0
  1. # coding: utf-8
  2.  
  3.  
  4. import copy
  5. from math import sqrt, sin, cos, isclose
  6.  
  7.  
  8. def find_determinant(M) -> float:
  9. """Wrapper function for 'determinant'"""
  10. if all(len(row) == len(M) for row in M):
  11. return determinant(M)
  12. else:
  13. raise ValueError('Non-square matrix')
  14.  
  15.  
  16. def determinant(M, det=0) -> float:
  17. """Обчислення детермінанта квадратної матриці M розмірності N >= 2 """
  18. ind = list(range(len(M)))
  19. if len(M) == 2 and len(M[0]) == 2:
  20. return M[0][0] * M[1][1] - M[1][0] * M[0][1]
  21. for i in ind:
  22. A = copy.deepcopy(M)[1:]
  23. for j in range(len(A)):
  24. A[j] = A[j][0:i] + A[j][i + 1:]
  25. sign = (-1) ** (i % 2)
  26. temp_det = determinant(A)
  27. det += sign * M[0][i] * temp_det
  28. return det
  29.  
  30.  
  31. def norm(a: list) -> float:
  32. """Евклідова норма вектора довільної розмірності
  33.  
  34. a - список координат вектора
  35. """
  36. return sqrt(sum(i ** 2 for i in a))
  37.  
  38.  
  39. def scale(a: list, C: float) -> list:
  40. """Множення вектора довільної розмірності на скаляр
  41.  
  42. a - список координат вектора
  43. C - скаляр
  44. """
  45. return [i * C for i in a]
  46.  
  47.  
  48. def add_vectors(a: list, b: list) -> list:
  49. """Сума двох векторів довільної розмірності
  50.  
  51. a, b - списки координат векторів
  52. """
  53. return [i + j for i, j in zip(a, b)]
  54.  
  55.  
  56. def subtract_vectors(a: list, b: list) -> list:
  57. """Різниця двох векторів довільної розмірності
  58.  
  59. a, b - списки координат векторів
  60. """
  61. if len(a) == len(b):
  62. return [i - j for i, j in zip(a, b)]
  63. else:
  64. raise ValueError
  65.  
  66.  
  67. def dot_product(a: list, b: list) -> float:
  68. """Скалярний добуток двох векторів довільної розмірності
  69.  
  70. a, b - списки координат векторів
  71. """
  72. if len(a) == len(b):
  73. return sum(i * j for i, j in zip(a, b))
  74. else:
  75. raise ValueError
  76.  
  77.  
  78. def cross_product(a: list, b: list) -> list:
  79. """Векторний добуток двох векторів у просторі
  80.  
  81. a, b - списки координат векторів
  82. """
  83. c = [a[1] * b[2] - a[2] * b[1],
  84. a[2] * b[0] - a[0] * b[2],
  85. a[0] * b[1] - a[1] * b[0]]
  86. return c
  87.  
  88.  
  89. def mixed_product(a: list, b: list, c: list) -> float:
  90. """Мішаний добуток трьох векторів у просторі
  91.  
  92. a, b, c - списки координат векторів
  93. """
  94. return find_determinant([a, b, c])
  95.  
  96.  
  97. def points_dist(M: list, N: list) -> float:
  98. """Евклідова відстань
  99.  
  100. M, N - координати точок
  101. """
  102. return sqrt(sum([(i - j) ** 2 for i, j in zip(M, N)]))
  103.  
  104.  
  105. def move_point(M: list, vector: list) -> list:
  106. """Переміщення точки вздовж вектора
  107.  
  108. vector - координати вектора
  109. M - координати точки
  110. """
  111. return add_vectors(M, vector)
  112.  
  113.  
  114. def turn_x_point(M: list, phi: float) -> list:
  115. """Поворот точки M відносно осі OX на кут phi"""
  116. return [M[0], M[1] * cos(phi) - M[2] * sin(phi), M[1] * sin(phi) + M[2] * cos(phi)]
  117.  
  118.  
  119. def turn_y_point(M: list, phi: float) -> list:
  120. """Поворот точки M відносно осі OY на кут phi"""
  121. return [M[0] * cos(phi) - M[2] * sin(phi), M[1], M[0] * sin(phi) + M[2] * cos(phi)]
  122.  
  123.  
  124. def turn_z_point(M: list, phi: float) -> list:
  125. """Поворот точки M відносно осі OZ на кут phi"""
  126. return [M[0] * cos(phi) - M[1] * sin(phi), M[0] * sin(phi) + M[1] * cos(phi), M[2]]
  127.  
  128.  
  129. def check_plane_correctness(coef: list) -> bool:
  130. """Перевірка корректності задання площини Ax+By+Cz+D=0
  131.  
  132. coef - список коефіцієнтів A,B,C,D загального рівняння площини
  133. """
  134. return not isclose(sum(abs(i) for i in coef[:-1]), 0)
  135.  
  136.  
  137. def get_plane(M: list, N: list, P: list) -> list:
  138. """Отримання списку коефіцієнтів A,B,C,D загального рівняння площини
  139. за допомогою трьох точок M, N, P, через які вона проходить
  140. """
  141. v1 = subtract_vectors(P, M)
  142. v2 = subtract_vectors(N, M)
  143. A, B, C = cross_product(v1, v2)
  144. D = -sum(i * j for i, j in zip((A, B, C), M))
  145. return [A, B, C, D]
  146.  
  147.  
  148. def point_on_plane(coef: list, p: list) -> bool:
  149. """Перевірка принадлежності точки площині
  150.  
  151. coef - список коефіцієнтів A,B,C,D загального рівняння площини
  152. p - координати точки у просторі
  153. """
  154. return isclose(coef[0] * p[0] + coef[1] * p[1] + coef[2] * p[2] + coef[3], 0)
  155.  
  156.  
  157. def point_on_line(coef1: list, coef2: list, p: list) -> bool:
  158. """Перевірка принадлежності точки лінії.
  159. Лінія визначається перетином двох площин
  160.  
  161. coef1 - список коефіцієнтів A,B,C,D загального рівняння першої площини
  162. coef2 -список коефіцієнтів A,B,C,D загального рівняння другої площини
  163. p - координати точки
  164. """
  165. return point_on_plane(coef1, p) and point_on_plane(coef2, p)
  166.  
  167.  
  168. def norm_plane(coef: list) -> list:
  169. """Нормування площини
  170.  
  171. coef - список коефіцієнтів A,B,C,D загального рівняння площини
  172. """
  173. n = sqrt(sum(i ** 2 for i in coef[:-1]))
  174. return [i / n for i in coef]
  175.  
  176.  
  177. def point_to_plane_dist(coef: list, p: list) -> float:
  178. """Відстань від точки до площини
  179.  
  180. coef - список коефіцієнтів A,B,C,D загального рівняння площини
  181. p - координати точки у просторі
  182. """
  183. if check_plane_correctness(coef):
  184. ncoef = norm_plane(coef)
  185. return ncoef[0] * p[0] + ncoef[1] * p[1] + ncoef[2] * p[2] + ncoef[3]
  186. else:
  187. raise ValueError
  188.  
  189.  
  190. def three_planes_intersect(coef1: list, coef2: list, coef3: list) -> list:
  191. """Знаходження точки перетину трьох площин
  192.  
  193. coef1, coef2, coef3 - списки коефіцієнтів A,B,C,D загальних рівнянь площин
  194. """
  195. c1 = check_plane_correctness(coef1[:-1])
  196. c2 = check_plane_correctness(coef2[:-1])
  197. c3 = check_plane_correctness(coef3[:-1])
  198. if c1 and c2 and c3:
  199. det = find_determinant([coef1[:-1], coef2[:-1], coef3[:-1]])
  200. print(det)
  201. if not isclose(det, 0):
  202. d = [coef1[-1], coef2[-1], coef3[-1]]
  203. detX = determinant([[coef1[-1], coef1[1], coef1[2]],
  204. [coef2[-1], coef2[1], coef2[2]],
  205. [coef3[-1], coef3[1], coef3[2]]])
  206. detY = determinant([[coef1[0], coef1[-1], coef1[2]],
  207. [coef2[0], coef2[-1], coef2[2]],
  208. [coef3[0], coef3[-1], coef3[2]]])
  209. detZ = determinant([[coef1[0], coef1[1], coef1[-1]],
  210. [coef2[0], coef2[1], coef2[-1]],
  211. [coef3[0], coef3[1], coef3[-1]]])
  212.  
  213. return [-detX / det, -detY / det, -detZ / det]
  214. else:
  215. return None
  216. else:
  217. raise ValueError
  218.  
  219.  
  220. def proj_point_on_plane(coef: list, p: list) -> list:
  221. """Проекція точки на площину
  222.  
  223. coef - список коефіцієнтів A,B,C,D загального рівняння площини
  224. p - координати точки у просторі
  225. """
  226. if check_plane_correctness(coef):
  227. A, B, C, D = coef
  228. t = - (A * p[0] + B * p[1] + C * p[2] + D) / (A ** 2 + B ** 2 + C ** 2)
  229. return [A * t + p[0], B * t + p[1], C * t + p[2]]
  230. else:
  231. raise ValueError
  232.  
  233.  
  234. def triangle_area_2d(A: list, B: list, C: list) -> float:
  235. """Обчислення площі трикутника на площині
  236.  
  237. A, B, C - координати вершин
  238. """
  239. v1 = subtract_vectors(B, A)
  240. v2 = subtract_vectors(C, A)
  241. return 0.5 * abs(find_determinant([v1, v2]))
  242.  
  243.  
  244. def triangle_area_3d(A: list, B: list, C: list) -> float:
  245. """Обчислення площі трикутника у просторі
  246.  
  247. A, B, C - координати вершин
  248. """
  249. v1 = subtract_vectors(B, A)
  250. v2 = subtract_vectors(C, A)
  251. return 0.5 * norm(cross_product(v1, v2))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement