def __init__(self, r, name='noname', v=Vector3d(0, 0), mass=1, color=(1, 1, 1)): self.r = r self.v = v self.name = name self.mass = mass self.force = Vector3d(0, 0) self.color = color
def __init__(self, side_str, device_addr=None, transposition=(0, 1, 2), scaling=(1, 1, 1)): self._accel = Vector3d(transposition, scaling, self._accel_callback) self._gyro = Vector3d(transposition, scaling, self._gyro_callback) self.buf1 = bytearray( 1) # Pre-allocated buffers for reads: allows reads to self.buf2 = bytearray(2) # be done in interrupt handlers self.buf3 = bytearray(3) self.buf6 = bytearray(6) sleep_ms(200) # Ensure PSU and device have settled #if(uname().sysname == 'WiPy'): # self._mpu_i2c = I2C(side_str) if isinstance(side_str, str): # Non-pyb targets may use other than X or Y self._mpu_i2c = I2C(side_str) elif isinstance(side_str, int): # WiPY targets self._mpu_i2c = I2C(side_str) elif hasattr(side_str, 'readfrom'): # Soft or hard I2C instance. See issue #3097 self._mpu_i2c = side_str else: raise ValueError("Invalid I2C instance") if device_addr is None: devices = set(self._mpu_i2c.scan()) mpus = devices.intersection(set(self._mpu_addr)) number_of_mpus = len(mpus) if number_of_mpus == 0: raise MPUException("No MPU's detected") elif number_of_mpus == 1: self.mpu_addr = mpus.pop() else: raise ValueError( "Two MPU's detected: must specify a device address") else: if device_addr not in (0, 1): raise ValueError('Device address must be 0 or 1') self.mpu_addr = self._mpu_addr[device_addr] self.chip_id # Test communication by reading chip_id: throws exception on error # Can communicate with chip. Set it up. self.wake() # wake it up self.passthrough = True # Enable mag access from main I2C bus self.accel_range = 0 # default to highest sensitivity self.gyro_range = 0 # Likewise for gyro
def __init__(self, side_str, device_addr, transposition, scaling): self._accel = Vector3d(transposition, scaling, self._accel_callback) self._gyro = Vector3d(transposition, scaling, self._gyro_callback) self.buf1 = bytearray( [0] * 1) # Pre-allocated buffers for reads: allows reads to self.buf2 = bytearray([0] * 2) # be done in interrupt handlers self.buf3 = bytearray([0] * 3) self.buf6 = bytearray([0] * 6) self.timeout = 10 # I2C tieout mS #tim = pyb.millis() # Ensure PSU and device have settled time.sleep(0.2) #if tim < 200: #pyb.delay(200-tim) if type(side_str) is str: sst = side_str.upper() if sst in {'X', 'Y'}: self._mpu_i2c = smbus.SMBus(1) #pyb.I2C(sst, pyb.I2C.MASTER) else: raise ValueError('I2C side must be X or Y') elif type(side_str) is pyb.I2C: self._mpu_i2c = side_str #self._mpu_i2c.scan if device_addr is None: devices = set(self._mpu_i2c.scan()) mpus = devices.intersection(set(self._mpu_addr)) number_of_mpus = len(mpus) if number_of_mpus == 0: raise MPUException("No MPU's detected") elif number_of_mpus == 1: self.mpu_addr = mpus.pop() else: raise ValueError( "Two MPU's detected: must specify a device address") else: if device_addr not in (0, 1): raise ValueError('Device address must be 0 or 1') self.mpu_addr = self._mpu_addr[device_addr] self.chip_id # Test communication by reading chip_id: throws exception on error # Can communicate with chip. Set it up. self.wake() # wake it up self.passthrough = True # Enable mag access from main I2C bus self.accel_range = 0 # default to highest sensitivity self.gyro_range = 0 # Likewise for gyro
def read(read_path, mode=None): particles = [] with open(read_path, 'r') as inputfile: s_tmp = inputfile.read() for el in s_tmp.split('\n')[2:]: if el != '': if mode is None: rx, ry, rz, r, g, b = el.split() else: c, rx, ry, rz, vx, vy, vz, c = el.split() particles.append( Particle(r=Vector3d(float(rx), float(ry), float(rz)), v=Vector3d(float(vx), float(vy), float(vz)), name=len(particles))) return particles
def create_sphere(radii, num_sumples=2000): cur_num_particles = 0 attempts = 100 particles = [] while True: u = np.random.uniform(0, 2 * np.pi) # v = np.random.uniform(0, np.pi) # cosu = np.random.uniform(-1, 1) cosv = np.random.uniform(-1, 1) tmp_z = np.random.uniform(0, 1) v = np.arccos(cosv) mul = tmp_z**(1 / 3) r1 = radii[0] * mul r2 = radii[1] * mul r3 = radii[2] * mul # mul = tmp_z**(1/2) # r1 = radii[0]*mul # r2 = radii[1]*mul # r3 = radii[2]*mul # lam = 0.1 # k = 0.00001 # r1 = radii[0]*(1-np.exp(tmp_z/lam)**k) # r2 = radii[1]*(1-np.exp(tmp_z/lam)**k) # r3 = radii[2]*(1-np.exp(tmp_z/lam)**k) # k = 1 # mul = -1/np.log(k - k*0.99999) * np.log(k - k*tmp_z) # r1 = radii[0]*mul # r2 = radii[1]*mul # r3 = radii[2]*mul # k = 1 # mul = (-1/(1+np.exp(-10*(tmp_z-0.5)))+1)**(1/3) # r1 = radii[0]*mul # r2 = radii[1]*mul # r3 = radii[2]*mul tmp = [ r1 * np.cos(u) * np.sin(v), r2 * np.sin(u) * np.sin(v), r3 * np.cos(v) ] if criterion(tmp, particles): # [x, y, z] = np.dot([tmp[0][0][0], tmp[1][0][0], tmp[2][0][0]], rotation) + center [x, y, z] = [tmp[0], tmp[1], tmp[2]] particles.append( Particle(r=Vector3d(x, y, z), color=(0, 0, 0), name=len(particles))) cur_num_particles += 1 if cur_num_particles % 1 == 0: print(cur_num_particles) if cur_num_particles == num_sumples: break return particles
def create_sphere2(radii, lengths, num_sumples=2000, mass=1): attempts = 100 # particles = [Particle(r=Vector3d(), mass=10)] particles = [] num = 100 for i in range(0, len(lengths) // num): cur_num_particles = 0 while True: u = np.random.uniform(0, 2*np.pi) cosv = np.random.uniform(-1, 1) tmp_z = np.random.uniform(0, 1) v = np.arccos(cosv) mul = tmp_z**(1/3) # mul = (mul * lengths[i*num + num-1]) + (lengths[i*num + num-1] - lengths[i*num]) mul = lengths[i*num] + mul*(lengths[i*num + num-1] - lengths[i*num]) r1 = radii[0]*mul r2 = radii[1]*mul r3 = radii[2]*mul tmp = [r1 * np.cos(u) * np.sin(v), r2 * np.sin(u) * np.sin(v), r3 * np.cos(v)] if criterion(tmp, particles): [x, y, z] = [tmp[0], tmp[1], tmp[2]] particles.append(Particle(r=Vector3d(x, y, z), mass=mass)) cur_num_particles += 1 # if cur_num_particles % 1 == 0: # print(cur_num_particles) if cur_num_particles == num//10: break return particles
def toVector3d(self): '''Return this NED vector as a 3-d vector. @return: The vector(north, east, down) (L{Vector3d}). ''' from vector3d import Vector3d return Vector3d(*self.to3ned(), name=self.name)
def greatCircle(self, bearing): '''Compute the vector normal to great circle obtained by heading on the given initial bearing from this point. Direction of vector is such that initial bearing vector b = c × n, where n is an n-vector representing this point. @param bearing: Bearing from this point (compass C{degrees360}). @return: Vector representing great circle (L{Vector3d}). @example: >>> p = LatLon(53.3206, -1.7297) >>> g = p.greatCircle(96.0) >>> g.toStr() # (-0.794, 0.129, 0.594) ''' a, b = self.to2ab() t = radians(bearing) ca, cb, ct = map1(cos, a, b, t) sa, sb, st = map1(sin, a, b, t) return Vector3d(sb * ct - cb * sa * st, -cb * ct - sb * sa * st, ca * st) # XXX .unit()?
def _x3d2(start, end, wrap, n): # see <http://www.EdWilliams.org/intersect.htm> (5) ff a1, b1 = start.to2ab() if isscalar(end): # bearing, make a point a2, b2 = _destination2_(a1, b1, PI_4, radians(end)) else: # must be a point _Trll.others(end, name='end' + n) a2, b2 = end.to2ab() db, b2 = unrollPI(b1, b2, wrap=wrap) if max(abs(db), abs(a2 - a1)) < EPS: raise ValueError('intersection %s%s null: %r' % ('path', n, (start, end))) # note, in EdWilliams.org/avform.htm W is + and E is - b21, b12 = db * 0.5, -(b1 + b2) * 0.5 cb21, cb12 = map1(cos, b21, b12) sb21, sb12 = map1(sin, b21, b12) sa21, sa12 = map1(sin, a1 - a2, a1 + a2) x = Vector3d(sa21 * sb12 * cb21 - sa12 * cb12 * sb21, sa21 * cb12 * cb21 + sa12 * sb12 * sb21, cos(a1) * cos(a2) * sin(db), ll=start) return x.unit(), (db, (a2 - a1)) # negated d
def from_matrix(self, matrix): """ Sets Atoms' coordinates from numpy.matrix(3,N) or(N,3). :param matrix: numpy.matrix(3, N or N, 3) """ if matrix.shape == (3, len(self)): for index, atom in enumerate(self.atoms): atom.coord = Vector3d(matrix[0, index], matrix[1, index], matrix[2, index]) elif matrix.shape == (len(self), 3): for index, atom in enumerate(self.atoms): atom.coord = Vector3d(matrix[index, 0], matrix[index, 1], matrix[index, 2]) else: raise Exception('Invalid matrix shape: ' + str(matrix.shape)) return self
def criterion(tmp, particles): tmp_particle = Particle(r=Vector3d(*tmp)) for particle in particles: # print((tmp_particle.r - particle.r).dot(forces.base_force(tmp_particle, particle))) # if (tmp_particle.r - particle.r).dot(forces.base_force(tmp_particle, particle)) > -0.3: if abs(tmp_particle.r - particle.r) < 0.5*constants.a: return False return True
def toVector3d(self): '''Convert this n-vector to a normalized 3-d vector, ignoring the height. @return: Normalized vector (L{Vector3d}). ''' u = self.unit() return Vector3d(u.x, u.y, u.z, name=self.name)
def __init__(self, device_addr=None, transposition=(0, 1, 2), scaling=(1, 1, 1), pins=None): self._accel = Vector3d(transposition, scaling, self._accel_callback) self._gyro = Vector3d(transposition, scaling, self._gyro_callback) self.buf1 = bytearray( 1) # Pre-allocated buffers for reads: allows reads to self.buf2 = bytearray(2) # be done in interrupt handlers self.buf3 = bytearray(3) self.buf6 = bytearray(6) sleep_ms(200) # Ensure PSU and device have settled if pins is not None: self._mpu_i2c = I2C(-1, mode=I2C.MASTER, pins=pins, baudrate=100000) else: self._mpu_i2c = I2C(0) if device_addr is None: devices = set(self._mpu_i2c.scan()) mpus = devices.intersection(set(self._mpu_addr)) number_of_mpus = len(mpus) if number_of_mpus == 0: raise MPUException("No MPU's detected") elif number_of_mpus == 1: self.mpu_addr = mpus.pop() else: raise ValueError( "Two MPU's detected: must specify a device address") else: if device_addr not in (0, 1): raise ValueError('Device address must be 0 or 1') self.mpu_addr = self._mpu_addr[device_addr] self.chip_id # Test communication by reading chip_id: throws exception on error # Can communicate with chip. Set it up. self.wake() # wake it up self.passthrough = True # Enable mag access from main I2C bus self.accel_range = 0 # default to highest sensitivity self.gyro_range = 0 # Likewise for gyro
def __init__(self, device_addr, busnum, transposition, scaling, mag_addr=None): '''Create an InvenSenseMPU interface. Arguments: device_addr (0 or 1): There are two possible I2C slave address for the MPU9x50. This value decides which of the two to use. busnum (integer): Which of the BeagleBone's I2C buses to use. transposition scaling mag_addr: I2C address of the magnetometer (different from the I2C ad dress of the main sensor). ''' self._accel = Vector3d(transposition, scaling, self._accel_callback) self._gyro = Vector3d(transposition, scaling, self._gyro_callback) self.buf1 = bytearray( [0] * 1) # Pre-allocated buffers for reads: allows reads to self.buf2 = bytearray([0] * 2) # be done in interrupt handlers self.buf3 = bytearray([0] * 3) self.buf6 = bytearray([0] * 6) self.timeout = 10 # I2C tieout mS if device_addr is None: raise ValueError("Adafruit_I2C does not support scanning") else: if device_addr not in (0, 1): raise ValueError('Device address must be 0 or 1') self.mpu_addr = self._mpu_addr[device_addr] self._mpu_i2c = Adafruit_I2C(self.mpu_addr, busnum=busnum) if mag_addr is not None: self._mag_i2c = Adafruit_I2C(mag_addr, busnum=busnum) self.chip_id # Test communication by reading chip_id: throws exception on error # Can communicate with chip. Set it up. self.wake() # wake it up self.passthrough = True # Enable mag access from main I2C bus self.accel_range = 0 # default to highest sensitivity self.gyro_range = 0 # Likewise for gyro
def toVector3d(self): '''Convert this point to a vector normal to earth's surface. @return: Vector representing this point (L{Vector3d}). ''' if self._v3d is None: x, y, z = self.to3xyz() self._v3d = Vector3d(x, y, z) # XXX .unit() return self._v3d
def __init__(self, side_str, device_addr=None, transposition=(0, 1, 2), scaling=(1, 1, 1)): super(MPU9250, self).__init__(side_str, device_addr, transposition, scaling) self._mag = Vector3d(transposition, scaling, self._mag_callback) self.accel_filter_range = 0 # fast filtered response self.gyro_filter_range = 0 self._mag_stale_count = 0 # MPU9250 count of consecutive reads where old data was returned self.mag_correction = self._magsetup() # 16 bit, 100Hz update.Return correction factors. self._mag_callback() # Seems neccessary to kick the mag off else 1st reading is zero (?)
def cent_of_mass(self): """ Returns a vector of the geometrical center of atoms. :return: Vector3d """ com = Vector3d() for atom in self.atoms: com += atom.coord return com / len(self)
def get_and_plot_density(particles, radii, rotation, center, num=100): cm = Vector3d() particles_ = copy.deepcopy(particles) derotation = np.linalg.inv(rotation) for particle in particles_: particle.r.x -= center[0] particle.r.y -= center[1] particle.r.z -= center[2] tmp = np.dot(np.array([particle.r.x, particle.r.y, particle.r.z]), derotation) particle.r = Vector3d(tmp[0], tmp[1], tmp[2]) cm += particle.r cm = cm * (1 / len(particles_)) for i in range(len(particles)): particles_[i].r.x *= 1 / radii[0] particles_[i].r.y *= 1 / radii[1] particles_[i].r.z *= 1 / radii[2] lengths = sorted([abs(particle.r) for particle in particles_]) density = [] l = [] # particles = sorted(particles, key=lambda particle: abs(particle.r - cm)) for i in range(len(lengths) // num): density.append(num * particles_[0].mass / (4 / 3 * np.pi * (lengths[i * num + num - 1]**3 - lengths[i * num]**3))) # l.append(lengths[i*num] + 0.5*(lengths[i*num + num-1] - lengths[i*num])) l.append(lengths[i * num]) ig, ax1 = plt.subplots(figsize=(4, 4)) ax1.scatter(x=l, y=density, marker='o', c='r', edgecolor='b') ax1.set_title('Scatter: $x$ versus $y$') ax1.set_xlabel('$x$') ax1.set_ylabel('$y$') plt.show() return density, lengths
def __init__(self, line=None, model=0, **kwargs): """ Constructor. Creates an Atom object from string - ATOM/HETATM line from the pdb file. If line is empty creates an empty atom equivalent to: Atom('HETATM 0 XXXX XXX X 0 0.000 0.000 0.000 0.00 0.00') Passing attribute=value to the constructor overwrites default/read values. :param line: str :param model: int """ if line: self.model = model self.hetatm = (line[:6] == "HETATM") self.serial = int(line[6:11]) self.name = line[11:16].strip() self.alt = line[16] self.resname = line[17:21].strip() self.chid = line[21] self.resnum = int(line[22:26]) self.icode = line[26] self.coord = Vector3d(line[30:38], line[38:46], line[46:54]) self.occ = float(line[54:60]) self.bfac = float(line[60:66]) self.tail = line[66:].replace('\n', '') else: self.model = model self.hetatm = True self.serial = 0 self.name = "XXXX" self.alt = "" self.resname = "XXX" self.chid = "X" self.resnum = 0 self.icode = "" self.coord = Vector3d() self.occ = 0.0 self.bfac = 0.0 self.tail = "" for arg in kwargs: if arg in self.__dict__: self.__dict__[arg] = kwargs[arg]
def __init__(self, side_str, device_addr=None, transposition=(0, 1, 2), scaling=(1, 1, 1)): super().__init__(side_str, device_addr, transposition, scaling) self._mag = Vector3d(transposition, scaling, self._mag_callback) self.filter_range = 0 # fast filtered response self._mag_stale_count = 0 # Count of consecutive reads where old data was returned self.mag_triggered = False # Ensure mag is triggered once only until it's read self.mag_correction = self._magsetup() # Returns correction factors. self.mag_wait_func = default_mag_wait
def insert_ligand(self, receptor, ligand): radius = 0.5 * receptor.dimension + self.separation if ligand.location == 'keep': location = ligand.cent_of_mass() elif ligand.location == 'random': location = Vector3d().random() * radius + receptor.center else: location = receptor.convert_patch( ligand.location) * radius + receptor.center if ligand.conformation == 'random': ligand.random_conformation() ligand.move_to(location)
def cast(self, ch): """ Function that casts a single protein chain onto the lattice. Returns a list of tuples with (x, y, z) coordinates of CA atoms. """ if len(ch.atoms) < 3: raise Exception('Protein chain too short!') prev = None coord = [ Vector3d(round(ch.atoms[0].coord.x / self.grid), round(ch.atoms[0].coord.y / self.grid), round(ch.atoms[0].coord.z / self.grid)) ] for atom in ch.atoms[1:]: # iterate over atoms min_dr = 1e12 min_i = -1 for i, v in enumerate(self.vectors): # iterate over all possible vectors if len(coord) > 2 and self.good[prev, i] == 0: continue new = coord[-1] + v dr = (self.grid * new - atom.coord).mod2() if dr < min_dr: min_dr = dr min_i = i if min_i < 0: raise Exception('Unsolvable geometric problem!') else: coord.append(coord[-1] + self.vectors[min_i]) prev = min_i coord.insert(0, coord[0] + coord[1] - coord[2]) coord.append(coord[-1] + coord[-2] - coord[-3]) return coord
def calculate_asa(atoms, probe, n_sphere_point=960): """ Returns list of accessible surface areas of the atoms, using the probe and atom radius to define the surface. """ sphere_points = generate_sphere_points(n_sphere_point) const = 4.0 * math.pi / len(sphere_points) test_point = Vector3d() areas = [] for i, atom_i in enumerate(atoms): neighbor_indices = find_neighbor_indices(atoms, probe, i) n_neighbor = len(neighbor_indices) j_closest_neighbor = 0 radius = probe + atom_i.radius n_accessible_point = 0 for point in sphere_points: is_accessible = True test_point.x = point[0] * radius + atom_i.pos.x test_point.y = point[1] * radius + atom_i.pos.y test_point.z = point[2] * radius + atom_i.pos.z cycled_indices = range(j_closest_neighbor, n_neighbor) cycled_indices.extend(range(j_closest_neighbor)) for j in cycled_indices: atom_j = atoms[neighbor_indices[j]] r = atom_j.radius + probe diff_sq = pos_distance_sq(atom_j.pos, test_point) if diff_sq < r * r: j_closest_neighbor = j is_accessible = False break if is_accessible: n_accessible_point += 1 area = const * n_accessible_point * radius * radius areas.append(area) return areas
def __init__(self, grid_spacing=0.61, r12=(3.28, 4.27), r13=(4.1, 7.35)): self.grid = grid_spacing r12min = round((r12[0] / self.grid)**2) r12max = round((r12[1] / self.grid)**2) r13min = round((r13[0] / self.grid)**2) r13max = round((r13[1] / self.grid)**2) dim = int(r12max**0.5) self.vectors = [] for i in range(-dim, dim + 1): for j in range(-dim, dim + 1): for k in range(-dim, dim + 1): l = i * i + j * j + k * k if r12min <= float(l) <= r12max: self.vectors.append(Vector3d(i, j, k)) n = len(self.vectors) self.good = np.zeros((n, n)) for i in range(n): vi = self.vectors[i] for j in range(n): vj = self.vectors[j] if r13min < (vi + vj).mod2() < r13max and vi.cross(vj).mod2(): self.good[i, j] = 1
input_path = '../3d/clust2.xyz' # input_path = '../3d/test/results_-999.xyz' save_path = os.path.dirname(os.path.realpath(__file__)) + '/test' if not os.path.exists(save_path): os.makedirs(save_path) particles = io_xyz.read(input_path, mode='Nick') print('Number of particles before: ', len(particles)) (center, radii, rotation) = getMinVolEllipse( np.array([[particle.r.x, particle.r.y, particle.r.z] for particle in particles], dtype='float32')) for particle in particles: particle.force = Vector3d() for i, p1 in enumerate(particles): print(i) for p2 in particles[i + 1:]: tmp_force = forces.base_force(p1, p2) p1.force += tmp_force p2.force += -tmp_force for particle in particles: R = np.sqrt(particle.r.y ** 2 + particle.r.z ** 2) velocity = np.sqrt(abs(particle.force) * R / particle.mass) e = Vector3d() e.x = particle.r.x e.y = particle.r.y
from vector3d import Vector3d from particle import Particle import numpy as np import io_xyz import forces import constants import random import copy import os save_path = os.path.dirname(os.path.realpath(__file__)) + '/test_force' if not os.path.exists(save_path): os.makedirs(save_path) particles = [ Particle(r=Vector3d(0, 0, 0)), Particle(r=Vector3d(constants.a_0 * 1.00000000000001, 0, 0)) ] for step in range(constants.steps_number): print('s', step) if step % 1000 == 0: io_xyz.write(particles, save_path, step) for particle in particles: particle.force = Vector3d() for i, p1 in enumerate(particles): for p2 in particles[i + 1:]: tmp_force = forces.base_force(p1, p2) p1.force += tmp_force
break return particles input_path = '../new/3d/clusters/clust1804.xyz' # input_path = '../3d/test/results_-999.xyz' save_path = os.path.dirname(os.path.realpath(__file__)) + '/test_good' if not os.path.exists(save_path): os.makedirs(save_path) particles = io_xyz.read(input_path, mode='Nick') print('Number of particles before: ', len(particles)) mean_vel = Vector3d() kinetic_energy = 0 for particle in particles: mean_vel += particle.v kinetic_energy += particle.mass * abs(particle.v)**2 / 2 mean_vel = mean_vel * (1 / len(particles)) omega = 0 for particle in particles: R = np.sqrt(particle.r.y**2 + particle.r.z**2) omega += abs(particle.v - mean_vel) / R omega /= len(particles) (center, radii, rotation) = getMinVolEllipse( np.array([[particle.r.x, particle.r.y, particle.r.z] for particle in particles],
get_and_plot_density(particles, radii, rotation, center, 10) # particles = [Particle(r=Vector3d(0,0,0)),Particle(r=Vector3d(1.5*constants.a,0,0))] # criterion([particles[0].r.x, particles[0].r.y, particles[0].r.z],[particles[1]]) for i, p1 in enumerate(particles): for p2 in particles[i + 1:]: if abs(p1.r - p2.r) < 0.5 * constants.a: print(abs(p1.r - p2.r)) print(len(particles)) omega = 5e-1 for particle in particles: R = np.sqrt(particle.r.y**2 + particle.r.z**2) e = Vector3d() e.x = 0 e.y = particle.r.y e.z = particle.r.z tmp_v = e * (1 / abs(e)) * omega * R # rotate pi/2 tmp = tmp_v.y tmp_v.y = tmp_v.z tmp_v.z = -tmp particle.v = tmp_v for step in range(constants.steps_number): print('s :', step) io_xyz.write(particles, save_path, step)
def toVector3d(self): '''Return this NED vector as a Vector3d. @return: North, east, down vector (L{Vector3d}). ''' return Vector3d(*self.to3ned())
u = np.random.sample() * 2.0 * np.pi v = np.random.sample() * np.pi r1 = np.random.sample() * radii[0] r2 = np.random.sample() * radii[1] r3 = np.random.sample() * radii[2] tmp = [ r1 * np.outer(np.cos(u), np.sin(v)), r2 * np.outer(np.sin(u), np.sin(v)), r3 * np.outer(np.ones_like(u), np.cos(v)) ] if criterier(tmp): [x, y, z] = np.dot([tmp[0][0][0], tmp[1][0][0], tmp[2][0][0]], rotation) + center particles.append( Particle(r=Vector3d(x, y, z), color=(0, 0, 0), name=len(particles))) k += 1 if k % 1000 == 0: print(k) if k == num_sumples: break # io_xyz.append_write(particles, save_path, 0) io_xyz.write(particles, save_path, -999) # particles = make_hex(constants.k, constants.l) # for step in range(constants.steps_number): # print(step)