cengal.math.geometry.ellipse.versions.v_0.ellipse
Module Docstring Docstrings: http://www.python.org/dev/peps/pep-0257/
1#!/usr/bin/env python 2# coding=utf-8 3 4# Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space> 5# 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17 18 19""" 20Module Docstring 21Docstrings: http://www.python.org/dev/peps/pep-0257/ 22""" 23 24from cengal.math.numbers import RationalNumber 25from cengal.time_management.repeat_for_a_time import Tracer 26from math import sqrt, pi, factorial 27 28__author__ = "ButenkoMS <gtalk@butenkoms.space>" 29__copyright__ = "Copyright © 2012-2024 ButenkoMS. All rights reserved. Contacts: <gtalk@butenkoms.space>" 30__credits__ = ["ButenkoMS <gtalk@butenkoms.space>", ] 31__license__ = "Apache License, Version 2.0" 32__version__ = "4.4.1" 33__maintainer__ = "ButenkoMS <gtalk@butenkoms.space>" 34__email__ = "gtalk@butenkoms.space" 35# __status__ = "Prototype" 36__status__ = "Development" 37# __status__ = "Production" 38 39class Ellipse: 40 """ 41 https://www.youtube.com/watch?v=5nW3nJhBHL0 42 http://www.ebyte.it/library/docs/math05a/EllipsePerimeterApprox05.html 43 """ 44 def __init__(self, a: RationalNumber, b: RationalNumber): 45 self.a = a 46 self.b = b 47 48 def y(self, x: RationalNumber) -> RationalNumber: 49 return self.b * sqrt(1 - (x / self.a)**2) 50 51 @property 52 def area(self): 53 return pi * self.a * self.b 54 55 @property 56 def h(self): 57 return ((self.a - self.b)**2) / ((self.a + self.b)**2) 58 59 @property 60 def e(self): 61 return sqrt(self.a**2 - self.b**2) / self.a 62 63 @property 64 def c(self): 65 return self.a * self.e 66 67 @property 68 def perimeter__kepler(self): 69 return 2 * pi * sqrt(self.a * self.b) 70 71 @property 72 def perimeter__naive(self): 73 return 2 * pi * ((self.a + self.b) / 2) 74 75 @property 76 def perimeter__euler(self): 77 return 2 * pi * sqrt((self.a**2 - self.b**2) / 2) 78 79 @property 80 def perimeter__matt_parker__lazy(self): 81 """Computationly efficient. Not more that 6.1% deviation (less than 5% for `1 / 75` ellipses) 82 83 Returns: 84 _type_: _description_ 85 """ 86 a = max(self.a, self.b) 87 b = min(self.a, self.b) 88 return pi * ((6 * a) / 5 + (3 * b) / 4) 89 90 @property 91 def perimeter__best_of__euler__and__matt_parker__lazy(self): 92 a = max(self.a, self.b) 93 b = min(self.a, self.b) 94 if (a / b) >= 0.8: 95 return self.perimeter__matt_parker__lazy 96 else: 97 return self.perimeter__euler 98 99 @property 100 def perimeter__ramanujan_1(self): 101 return pi * (3 * (self.a + self.b) - sqrt((3 * self.a + self.b) * (self.a + 3 * self.b))) 102 103 @property 104 def perimeter__matt_parker__precise(self): 105 a = max(self.a, self.b) 106 b = min(self.a, self.b) 107 return pi * ((53 * a) / 3 + (717 * b) / 35 - sqrt(269 * a ** 2 + 667 * a * b + 371 * b ** 2)) 108 109 @property 110 def perimeter__best_of__ramanujan_1__and__matt_parker__precise(self): 111 a = max(self.a, self.b) 112 b = min(self.a, self.b) 113 if (a / b) >= 2.4: 114 return self.perimeter__matt_parker__precise 115 else: 116 return self.perimeter__ramanujan_1 117 118 @property 119 def perimeter__ramanujan_2(self): 120 return pi * (self.a + self.b) * (1 + (3 * self.h) / (10 + sqrt(4 - 3 * self.h))) 121 122 def perimeter__infinite_sum__time_lim(self, desired_approximation_time: float, return_iterations_num: bool = False): 123 e = self.e 124 first_multiplier = 2 * self.a * pi 125 second_multiplier = 1 126 tr = Tracer(desired_approximation_time) 127 while tr.iter(): 128 i = tr.total_number_of_iterations_made 129 second_multiplier -= ((factorial(2 * i) ** 2) / ((2 ** i * factorial(i)) ** 4)) * ((e ** (2 * i)) / (2 * i - 1)) 130 131 if return_iterations_num: 132 return first_multiplier * second_multiplier, tr.total_number_of_iterations_made 133 else: 134 return first_multiplier * second_multiplier 135 136 def perimeter__infinite_sum__iter_lim(self, iterations_num: int): 137 e = self.e 138 first_multiplier = 2 * self.a * pi 139 second_multiplier = 1 140 for i in range(1, iterations_num + 1): 141 second_multiplier -= ((factorial(2 * i) ** 2) / ((2 ** i * factorial(i)) ** 4)) * ((e ** (2 * i)) / (2 * i - 1)) 142 143 return first_multiplier * second_multiplier 144 145 @staticmethod 146 def from_r1_r2(r1: RationalNumber, r2: RationalNumber): 147 return Ellipse((r1 + r2) / 2, 1)
class
Ellipse:
40class Ellipse: 41 """ 42 https://www.youtube.com/watch?v=5nW3nJhBHL0 43 http://www.ebyte.it/library/docs/math05a/EllipsePerimeterApprox05.html 44 """ 45 def __init__(self, a: RationalNumber, b: RationalNumber): 46 self.a = a 47 self.b = b 48 49 def y(self, x: RationalNumber) -> RationalNumber: 50 return self.b * sqrt(1 - (x / self.a)**2) 51 52 @property 53 def area(self): 54 return pi * self.a * self.b 55 56 @property 57 def h(self): 58 return ((self.a - self.b)**2) / ((self.a + self.b)**2) 59 60 @property 61 def e(self): 62 return sqrt(self.a**2 - self.b**2) / self.a 63 64 @property 65 def c(self): 66 return self.a * self.e 67 68 @property 69 def perimeter__kepler(self): 70 return 2 * pi * sqrt(self.a * self.b) 71 72 @property 73 def perimeter__naive(self): 74 return 2 * pi * ((self.a + self.b) / 2) 75 76 @property 77 def perimeter__euler(self): 78 return 2 * pi * sqrt((self.a**2 - self.b**2) / 2) 79 80 @property 81 def perimeter__matt_parker__lazy(self): 82 """Computationly efficient. Not more that 6.1% deviation (less than 5% for `1 / 75` ellipses) 83 84 Returns: 85 _type_: _description_ 86 """ 87 a = max(self.a, self.b) 88 b = min(self.a, self.b) 89 return pi * ((6 * a) / 5 + (3 * b) / 4) 90 91 @property 92 def perimeter__best_of__euler__and__matt_parker__lazy(self): 93 a = max(self.a, self.b) 94 b = min(self.a, self.b) 95 if (a / b) >= 0.8: 96 return self.perimeter__matt_parker__lazy 97 else: 98 return self.perimeter__euler 99 100 @property 101 def perimeter__ramanujan_1(self): 102 return pi * (3 * (self.a + self.b) - sqrt((3 * self.a + self.b) * (self.a + 3 * self.b))) 103 104 @property 105 def perimeter__matt_parker__precise(self): 106 a = max(self.a, self.b) 107 b = min(self.a, self.b) 108 return pi * ((53 * a) / 3 + (717 * b) / 35 - sqrt(269 * a ** 2 + 667 * a * b + 371 * b ** 2)) 109 110 @property 111 def perimeter__best_of__ramanujan_1__and__matt_parker__precise(self): 112 a = max(self.a, self.b) 113 b = min(self.a, self.b) 114 if (a / b) >= 2.4: 115 return self.perimeter__matt_parker__precise 116 else: 117 return self.perimeter__ramanujan_1 118 119 @property 120 def perimeter__ramanujan_2(self): 121 return pi * (self.a + self.b) * (1 + (3 * self.h) / (10 + sqrt(4 - 3 * self.h))) 122 123 def perimeter__infinite_sum__time_lim(self, desired_approximation_time: float, return_iterations_num: bool = False): 124 e = self.e 125 first_multiplier = 2 * self.a * pi 126 second_multiplier = 1 127 tr = Tracer(desired_approximation_time) 128 while tr.iter(): 129 i = tr.total_number_of_iterations_made 130 second_multiplier -= ((factorial(2 * i) ** 2) / ((2 ** i * factorial(i)) ** 4)) * ((e ** (2 * i)) / (2 * i - 1)) 131 132 if return_iterations_num: 133 return first_multiplier * second_multiplier, tr.total_number_of_iterations_made 134 else: 135 return first_multiplier * second_multiplier 136 137 def perimeter__infinite_sum__iter_lim(self, iterations_num: int): 138 e = self.e 139 first_multiplier = 2 * self.a * pi 140 second_multiplier = 1 141 for i in range(1, iterations_num + 1): 142 second_multiplier -= ((factorial(2 * i) ** 2) / ((2 ** i * factorial(i)) ** 4)) * ((e ** (2 * i)) / (2 * i - 1)) 143 144 return first_multiplier * second_multiplier 145 146 @staticmethod 147 def from_r1_r2(r1: RationalNumber, r2: RationalNumber): 148 return Ellipse((r1 + r2) / 2, 1)
https://www.youtube.com/watch?v=5nW3nJhBHL0 http://www.ebyte.it/library/docs/math05a/EllipsePerimeterApprox05.html
perimeter__matt_parker__lazy
80 @property 81 def perimeter__matt_parker__lazy(self): 82 """Computationly efficient. Not more that 6.1% deviation (less than 5% for `1 / 75` ellipses) 83 84 Returns: 85 _type_: _description_ 86 """ 87 a = max(self.a, self.b) 88 b = min(self.a, self.b) 89 return pi * ((6 * a) / 5 + (3 * b) / 4)
Computationly efficient. Not more that 6.1% deviation (less than 5% for 1 / 75
ellipses)
Returns: _type_: _description_
def
perimeter__infinite_sum__time_lim( self, desired_approximation_time: float, return_iterations_num: bool = False):
123 def perimeter__infinite_sum__time_lim(self, desired_approximation_time: float, return_iterations_num: bool = False): 124 e = self.e 125 first_multiplier = 2 * self.a * pi 126 second_multiplier = 1 127 tr = Tracer(desired_approximation_time) 128 while tr.iter(): 129 i = tr.total_number_of_iterations_made 130 second_multiplier -= ((factorial(2 * i) ** 2) / ((2 ** i * factorial(i)) ** 4)) * ((e ** (2 * i)) / (2 * i - 1)) 131 132 if return_iterations_num: 133 return first_multiplier * second_multiplier, tr.total_number_of_iterations_made 134 else: 135 return first_multiplier * second_multiplier
def
perimeter__infinite_sum__iter_lim(self, iterations_num: int):
137 def perimeter__infinite_sum__iter_lim(self, iterations_num: int): 138 e = self.e 139 first_multiplier = 2 * self.a * pi 140 second_multiplier = 1 141 for i in range(1, iterations_num + 1): 142 second_multiplier -= ((factorial(2 * i) ** 2) / ((2 ** i * factorial(i)) ** 4)) * ((e ** (2 * i)) / (2 * i - 1)) 143 144 return first_multiplier * second_multiplier