Advertisement
KrimsN

montecarlo

May 29th, 2020
567
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.10 KB | None | 0 0
  1. from math import pi, sqrt
  2. from functools import reduce
  3. from operator import mul
  4. import random
  5. import pandas as pd
  6.  
  7.  
  8. points = {'x': [], 'y': [], 'z': []}
  9.  
  10.  
  11. class Ball:
  12.     def __init__(self, coords, radius):
  13.         self.coords = coords
  14.         self.radius = radius
  15.        
  16.     def __contains__(self, point):
  17.         return sum((a-b)**2 for a, b in zip(self.coords, point)) <= self.radius ** 2
  18.        
  19.     def aabb(self):
  20.         low = tuple(c-self.radius for c in self.coords)
  21.         high = tuple(c+self.radius for c in self.coords)
  22.         return low, high
  23.        
  24.     def volume(self):
  25.         return 4/3 * pi * self.radius ** 3
  26.  
  27.  
  28. class Torus:
  29.     # R - расстояние от оси вращения до образующей,
  30.     # r - радиус образующей
  31.     def __init__(self, coords, R, r):
  32.         self.coords = coords
  33.         self.R = R
  34.         self.r = r
  35.        
  36.     def __contains__(self, point):
  37.         diff = tuple(p-s for s, p in zip(self.coords, point))
  38.         Rs = sqrt(diff[0]**2 + diff[1]**2)
  39.         Rr = self.R - Rs
  40.         return diff[2]**2 + Rr**2 <= self.r ** 2
  41.        
  42.     def aabb(self):
  43.         c = self.coords
  44.         low = (c[0]-self.r-self.R, c[1]-self.r-self.R, c[2]-self.r)
  45.         high = (c[0]+self.r+self.R, c[1]+self.r+self.R, c[2]+self.r)
  46.         return low, high
  47.        
  48.     def volume(self):
  49.         return 2 * pi * pi * self.R * self.r * self.r
  50.        
  51.        
  52. class Pair:
  53.     def __init__(self, f1, f2):
  54.         self.f1 = f1
  55.         self.f2 = f2
  56.        
  57.     def __contains__(self, point):
  58.         return point in self.f1 or point in self.f2
  59.        
  60.     def aabb(self):
  61.         a1 = self.f1.aabb()
  62.         a2 = self.f2.aabb()
  63.         low = tuple(min(a, b) for a, b in zip(a1[0], a2[0]))
  64.         high = tuple(max(a, b) for a, b in zip(a1[1], a2[1]))
  65.         return low, high
  66.        
  67.     def volume(self):
  68.         return self.f1.volume() + self.f2.volume()
  69.  
  70. def make_point(aabb, fig):
  71.     def foo(x, i):
  72.         low = aabb[0][i]
  73.         high = aabb[1][i]
  74.         return low+(high-low)*x
  75.  
  76.     r = random.random
  77.     p = tuple(foo(r(),i) for i in range(3))
  78.  
  79.     global points
  80.     if p in fig:
  81.         points['x'].append(p[0])
  82.         points['y'].append(p[1])
  83.         points['z'].append(p[2])
  84.  
  85.     return p
  86.    
  87. def run_tests(box, fig, n):
  88.     S = reduce(mul, (box[1][c]-box[0][c] for c in range(3)), 1.0)
  89.     print(f'Объём коробки: {S}')
  90.     Ng = sum(make_point(box, fig) in fig for i in range(n))
  91.     print(f'Удачных поподаний: {Ng}, всего поподаний: {N}')
  92.     Sf = Ng / N * S
  93.  
  94.     print(f'СКО: {sqrt((N-Ng)/(N*Ng))}')
  95.     print(f'Теоретический объём: {F.volume()}, вычесленный объём: {Sf}')
  96.  
  97.  
  98. if __name__ == "__main__":
  99.     random.seed()
  100.  
  101.     ball_radius = 1.0
  102.     ball_c = (0.0, 0.0, 0.0)
  103.  
  104.     torus_R = 3.0
  105.     torus_r = 1.0
  106.     torus_c = (0.0, 0.0, 6.0)
  107.  
  108.     B = Ball(ball_c, ball_radius)
  109.     T = Torus(torus_c, torus_R, torus_r)
  110.     F = Pair(B, T)
  111.  
  112.     AABB = F.aabb()
  113.     print(f'границы проверяемой коробки{AABB}')
  114.  
  115.    
  116.     N=10**4
  117.    
  118.     run_tests(AABB, F, N)
  119.  
  120.  
  121.     from mpl_toolkits.mplot3d import Axes3D
  122.     import matplotlib.pyplot as plt
  123.     import numpy as np
  124.    
  125.  
  126.     fig = plt.figure()
  127.     ax = fig.add_subplot(111, projection='3d')
  128.     ax.scatter(points['x'], points['y'], points['z'], marker='o')
  129.     ax.set_xlabel('X ')
  130.     ax.set_ylabel('Y ')
  131.     ax.set_zlabel('Z ')
  132.  
  133.     plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement