-
Notifications
You must be signed in to change notification settings - Fork 1
/
cardioid.py
90 lines (71 loc) · 2.51 KB
/
cardioid.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# from cmath import sqrt
from math import atan2, sin, pi, sqrt
import random as r
mutation_rate = 0.5
ARRAY_SIZE = 10
class Cordinate:
def __init__(self, n) -> None:
self.decimal = int(n)
self.binary = self.int_to_binary(int(self.decimal))
self.gray_code = self.binary_to_gray(self.binary)
def flip_bit(self, binary, index):
binary_list = list(binary)
if binary_list[index] == "0":
binary_list[index] = "1"
else:
"0"
return ''.join(binary_list)
def mutate(self):
mutation_index = r.randint(0, len(self.gray_code) - 1)
mutated_gray_code = self.flip_bit(str(self.gray_code), mutation_index)
self.gray_code = mutated_gray_code
self.binary = self.gray_to_binary(self.gray_code)
self.decimal = int(self.binary, 2)
def gray_to_binary(self, n):
n = int(n, 2)
mask = n
while mask != 0:
mask >>= 1
n ^= mask
return bin(n)[2:]
def int_to_binary(self, n):
binary_string = ""
while n > 0:
binary_string += str(n % 2)
n //= 2
while len(binary_string) < ARRAY_SIZE:
binary_string = "0" + binary_string
return binary_string
def binary_to_gray(self, n):
n = int(n, 2)
n ^= (n >> 1)
gray_code = bin(n)[2:]
while len(gray_code) < ARRAY_SIZE:
gray_code = "0" + gray_code
return gray_code
class Cardioid:
def __init__(self, x, y, size) -> None:
self.x_cordinate = Cordinate(x)
self.y_cordinate = Cordinate(y)
self.size = Cordinate(size)
def is_inside_cardioid(self, x, y):
size = self.size.decimal
x_c = self.x_cordinate.decimal
y_c = self.y_cordinate.decimal
r = size / 2
# distance = math.sqrt((x - x_c) ** 2 + (y - y_c) ** 2)
theta = atan2(y - y_c, x - x_c)
cardioid_equation = ((x - x_c) ** 2 + (y - y_c) ** 2) <= r ** 2 * (1 - sin(theta))
return cardioid_equation
def will_mutate(self, mutation_rate):
return r.uniform(0, 1) < mutation_rate
def mutate(self):
has_x_mutated = self.will_mutate(mutation_rate)
has_y_mutated = self.will_mutate(mutation_rate)
has_radius_mutated = self.will_mutate(mutation_rate)
if has_x_mutated:
self.x_cordinate.mutate()
if has_y_mutated:
self.y_cordinate.mutate()
if has_radius_mutated:
self.size.mutate()