def __constrain(self, vector, axis): """ private constrain (used to constrain axis) """ res = PVector.sub(vector, PVector.mult(axis, PVector.dot(axis, vector))) res.normalize() return res
def spawn(self, **kwargs): # position = kwargs.pop('position') vel = kwargs.get('velocity', PVector(0, 0, 0)) kwargs['velocity'] = PVector( *[sum([s_i, v_i]) for s_i, v_i in zip(self.spawn_velocity, vel)]) if len(self) > self.capacity: self.pop(0) self.append(Particle(**kwargs))
def step(self, field=None): if field: self.velocity = PVector( *[sum([v_i, f_i]) for (v_i, f_i) in zip(self.velocity, field)]) if self.velocity: self.position = PVector(*[ sum([p_i, v_i]) for (p_i, v_i) in zip(self.position, self.velocity) ])
def draw(): """ Required for pyprocessing.run() """ global screen_size global camera_pos global spawner global frame_count global swarm global back_col global img_dir pyp.camera(camera_pos.x, camera_pos.y, camera_pos.z, 0, 0, 0, 1, 0, 0) s = max(screen_size) pyp.pointLight(255, 255, 255, 10 * s, 0, 0) pyp.pointLight(255, 255, 255, 0, 10 * s, 0) pyp.pointLight(255, 255, 255, 0, 0, 10 * s) pyp.background(back_col) #calculate spawner angle animation_angle = 2.0 * pi * (frame_count % frame_cycles) / frame_cycles spawner.angle = 65 * animation_angle # print 'spawner', pformat({ # 'angle':spawner.angle, # 'position':spawner.spawn_position # }) seed(animation_angle) swarm.spawn(orientation=PVector(s / 50, 0, 0), position=spawner.spawn_position, velocity=PVector((sin(animation_angle)) * s / 100, (cos(animation_angle)) * s / 100, (1 - random() * 2) * s / 100), active=True) for particle in swarm: # print 'particle', pformat({ # 'position': particle.position, # 'velocity': particle.velocity, # 'orientation': particle.orientation # }) particle.draw() particle.step() frame_count += 1 if frame_count in range(360, 720): img = pyp.get() # print type(img) pyp.save(os.path.join(img_dir, 'image_%s.jpg' % (frame_count)))
def mouseDragged(self, x, y): """ pass in mouse.x and mouse.y parameters from sketch """ self.v_drag = self.__mouse2sphere(x, y) self.q_drag.set(PVector.dot(self.v_down, self.v_drag), self.v_down.cross(self.v_drag))
def transform(cls, transformation, vector): assert isinstance(transformation, np.ndarray) assert isinstance(vector, PVector) # if transformation is 3x3 then vector should be 3 assert all( [len(vector) == dimension for dimension in transformation.shape]) response = np.matmul(transformation, vector) return PVector(*response)
def spawn_position(self): circle = PVector(self.size * sin(self.angle), self.size * cos(self.angle), 0) (r, theta, phi) = self.orientation_spherical if theta: circle = Transformation.rotate_y(-theta, circle) if phi: circle = Transformation.rotate_z(phi, circle) if self.position: circle = Transformation.transpose(self.position, circle) return circle
def setup(): """ Required for pyprocessing.run() """ global screen_size # size of the raster canvas global camera_pos # PVector of camera's position global spawner # an object used for spawning particles global frame_count # number of framse currently global swarm # Collection of background partciles global img_dir # dir where frames are stored run_stamp = time.strftime("%Y-%m-%d_%H-%M-%S") img_dir = './images/%s' % run_stamp if not os.path.exists(img_dir): os.makedirs(img_dir) frame_count = 0 s = max(screen_size) camera_pos = PVector(0, 0, s) spawner = Spawner(position=PVector(0, 0, s), orientation=PVector(0, 0, s / 10)) swarm = Swarm(spawn_velocity=PVector(0, 0, -s / 40), capacity=background_particle_count)
def __init__(self, cx, cy, radius): """ Initialize instance of ArcBall with no constraint on axis of rotation """ self.center_x = cx self.center_y = cy self.radius = radius self.v_down = PVector() self.v_drag = PVector() self.q_now = Quaternion() self.q_down = Quaternion() self.q_drag = Quaternion() self.axisSet = [PVector(1.0, 0.0, 0.0), PVector(0.0, 1.0, 0.0), PVector(0.0, 0.0, 1.0)] self.axis = -1
def __mouse2sphere(self, x, y): """ private map mouse to ArcBall (sphere) """ v = PVector() v.x = (x - self.center_x) / self.radius v.y = (y - self.center_y) / self.radius mag = v.x * v.x + v.y * v.y if (mag > 1.0): v.normalize() else: v.z = sqrt(1.0 - mag) if (self.axis != -1): v = self.__constrain(v, self.axis_set[self.axis]) return v
def __mouse2sphere(self, x, y): """ private map mouse to ArcBall (sphere) """ v = PVector() v.x = (x - self.center_x) / self.radius v.y = (y - self.center_y) / self.radius mag = v.x * v.x + v.y * v.y if mag > 1.0: v.normalize() else: v.z = sqrt(1.0 - mag) return v if (self.axis == -1) else (self.__constrain(v, self.axisSet[self.axis]))
def __init__(self, cx, cy, radius): """ Initialize instance of ArcBall with no constraint on axis of rotation """ self.center_x = cx self.center_y = cy self.radius = radius self.v_down = PVector() self.v_drag = PVector() self.q_now = Quaternion() self.q_down = Quaternion() self.q_drag = Quaternion() self.axis_set = [ PVector(1.0, 0.0, 0.0), PVector(0.0, 1.0, 0.0), PVector(0.0, 0.0, 1.0) ] self.axis = -1
def transpose(cls, offset, vector): return PVector(*[sum(elems) for elems in zip(offset, vector)])
class ArcBall(object): """ Class for provides intuitive 3d manipulation of sketch object in pyprocessing. ArcBall class uses Quaternions class for efficient calculation of rotation. Hold down x, y or z keys to constrain rotation to that plane; otherwise drag mouse for smooth rotation Written by Martin Prout - see https://github.com/monkstone/pyprocessing-experiments """ def __init__(self, cx, cy, radius): """ Initialize instance of ArcBall with no constraint on axis of rotation """ self.center_x = cx self.center_y = cy self.radius = radius self.v_down = PVector() self.v_drag = PVector() self.q_now = Quaternion() self.q_down = Quaternion() self.q_drag = Quaternion() self.axis_set = [PVector(1.0, 0.0, 0.0), PVector(0.0, 1.0, 0.0), PVector(0.0, 0.0, 1.0)] self.axis = -1 def selectAxis(self, axis): """ call this from sketch (typically in keyPressed() to constrain rotation to one axis) valid input 0, 1, 2 or -1 """ self.axis = axis def __mouse2sphere(self, x, y): """ private map mouse to ArcBall (sphere) """ v = PVector() v.x = (x - self.center_x) / self.radius v.y = (y - self.center_y) / self.radius mag = v.x * v.x + v.y * v.y if (mag > 1.0) : v.normalize() else: v.z = sqrt(1.0 - mag) if (self.axis != -1): v = self.__constrain(v, self.axis_set[self.axis]) return v def mousePressed(self, x, y): """ pass in mouse.x and mouse.y parameters from sketch """ self.v_down = self.__mouse2sphere(x, y) self.q_down.copy(self.q_now) self.q_drag.reset() def mouseDragged(self, x, y): """ pass in mouse.x and mouse.y parameters from sketch """ self.v_drag = self.__mouse2sphere(x, y) self.q_drag.set(PVector.dot(self.v_down, self.v_drag), self.v_down.cross(self.v_drag)) def __constrain(self, vector, axis): """ private constrain (used to constrain axis) """ res = PVector.sub(vector, PVector.mult(axis, PVector.dot(axis, vector))) res.normalize() return res def update(self): """ Call this function in the sketch draw loop to get rotation matrix as an array """ self.q_now = Quaternion.mult(self.q_drag, self.q_down) return self.__quat2matrix(self.q_now) def __quat2matrix(self, q) : """ private return matrix as array """ rot = q.getValue() return rot
class ArcBall(object): """ Class for provides intuitive 3d manipulation of sketch object in pyprocessing. ArcBall class uses Quaternions class for efficient calculation of rotation. Hold down x, y or z keys to constrain rotation to that plane; otherwise drag mouse for smooth rotation Written by Martin Prout - see https://github.com/monkstone/pyprocessing-experiments """ def __init__(self, cx, cy, radius): """ Initialize instance of ArcBall with no constraint on axis of rotation """ self.center_x = cx self.center_y = cy self.radius = radius self.v_down = PVector() self.v_drag = PVector() self.q_now = Quaternion() self.q_down = Quaternion() self.q_drag = Quaternion() self.axis_set = [ PVector(1.0, 0.0, 0.0), PVector(0.0, 1.0, 0.0), PVector(0.0, 0.0, 1.0) ] self.axis = -1 def selectAxis(self, axis): """ call this from sketch (typically in keyPressed() to constrain rotation to one axis) valid input 0, 1, 2 or -1 """ self.axis = axis def __mouse2sphere(self, x, y): """ private map mouse to ArcBall (sphere) """ v = PVector() v.x = (x - self.center_x) / self.radius v.y = (y - self.center_y) / self.radius mag = v.x * v.x + v.y * v.y if (mag > 1.0): v.normalize() else: v.z = sqrt(1.0 - mag) if (self.axis != -1): v = self.__constrain(v, self.axis_set[self.axis]) return v def mousePressed(self, x, y): """ pass in mouse.x and mouse.y parameters from sketch """ self.v_down = self.__mouse2sphere(x, y) self.q_down.copy(self.q_now) self.q_drag.reset() def mouseDragged(self, x, y): """ pass in mouse.x and mouse.y parameters from sketch """ self.v_drag = self.__mouse2sphere(x, y) self.q_drag.set(PVector.dot(self.v_down, self.v_drag), self.v_down.cross(self.v_drag)) def __constrain(self, vector, axis): """ private constrain (used to constrain axis) """ res = PVector.sub(vector, PVector.mult(axis, PVector.dot(axis, vector))) res.normalize() return res def update(self): """ Call this function in the sketch draw loop to get rotation matrix as an array """ self.q_now = Quaternion.mult(self.q_drag, self.q_down) return self.__quat2matrix(self.q_now) def __quat2matrix(self, q): """ private return matrix as array """ rot = q.getValue() return rot
class ArcBall(object): """ Class contains ArcBall logic see test_arcball.py for usage """ def __init__(self, cx, cy, radius): """ Initialize instance of ArcBall with no constraint on axis of rotation """ self.center_x = cx self.center_y = cy self.radius = radius self.v_down = PVector() self.v_drag = PVector() self.q_now = Quaternion() self.q_down = Quaternion() self.q_drag = Quaternion() self.axisSet = [PVector(1.0, 0.0, 0.0), PVector(0.0, 1.0, 0.0), PVector(0.0, 0.0, 1.0)] self.axis = -1 def selectAxis(self, axis): """ call this from sketch (typically in keyPressed() to constrain rotation to one axis) valid input 0, 1, 2 or -1 """ self.axis = axis def __mouse2sphere(self, x, y): """ private map mouse to ArcBall (sphere) """ v = PVector() v.x = (x - self.center_x) / self.radius v.y = (y - self.center_y) / self.radius mag = v.x * v.x + v.y * v.y if mag > 1.0: v.normalize() else: v.z = sqrt(1.0 - mag) return v if (self.axis == -1) else (self.__constrain(v, self.axisSet[self.axis])) def mousePressed(self, x, y): """ pass in mouse.x and mouse.y parameters from sketch """ self.v_down = self.__mouse2sphere(x, y) self.q_down.copy(self.q_now) self.q_drag.reset() def mouseDragged(self, x, y): """ pass in mouse.x and mouse.y parameters from sketch """ self.v_drag = self.__mouse2sphere(x, y) self.q_drag.set(PVector.dot(self.v_down, self.v_drag), self.v_down.cross(self.v_drag)) def __constrain(self, vector, axis): """ private constrain (used to constrain axis) """ res = PVector.sub(vector, PVector.mult(axis, PVector.dot(axis, vector))) res.normalize() return res def update(self): """ Call this function in the sketch draw loop to get rotation matrix as an array """ self.q_now = Quaternion.mult(self.q_drag, self.q_down) return self.__quat2matrix(self.q_now) def __quat2matrix(self, q): """ private return matrix as array """ rot = q.getValue() return rot
def cartesian_to_spherical(cls, vector): length = vector.mag() azimuth = np.arctan2(vector.x, vector.y) polar = cls.angle_between(PVector(0, 0, 1), vector) return (length, polar, azimuth)
def __init__(self, **kwargs): self.capacity = kwargs.pop('capacity', 100) self.spawn_velocity = kwargs.pop('spawn_velocity', PVector(-1, 0, 0)) Drawable.__init__(self, **kwargs) list.__init__(self, **kwargs)
class TestPVectorMethods(unittest.TestCase): def setUp(self): self.A = PVector(1, 0) self.B = PVector(0, 5) self.C = PVector(3,4) self.D = PVector(4, 4) def test_cross(self): # <1, 0> x <0, 5> = 5 - 0 = 5 self.assertEqual(self.A.cross(self.B), 5) # switching order should be inverse self.assertEqual(self.B.cross(self.A), -5) def test_dot(self): # <3, 4> * <4, 4> = 3*4 + 4*4 = 12 + 16 = 28 self.assertEqual(self.C.dot(self.D), 28) def test_mag(self): # sqrt(3**2 + 4**2) = 5 self.assertEqual(self.C.mag(), 5) def test_theta(self): self.assertEqual(self.A.theta(), 0) self.assertEqual(self.B.theta(), 90) self.assertEqual(self.D.theta(), 45) def test_theta_radians(self): # 45 degrees is pi/4 self.assertAlmostEqual(self.D.theta(degree=False), 3.14159/4.0, places=2) def test_setMag(self): self.A.setMag(self.B.mag()) self.assertEqual(self.A.mag(), self.B.mag()) def test_scale(self): self.B.scale(2) # 2 * 5 is 10 self.assertEqual(self.B.mag(), 10) self.B.scale(-2) # opposite length is still length self.assertEqual(self.B.mag(), 20) def test_norm(self): self.C.norm() self.assertEqual(self.C.mag(), 1) def test_rotate(self): self.A.rotate(90) self.assertEqual(self.A.theta(), self.B.theta()) def test_angle_between(self): self.A.x, self.A.y = 0, 1 self.assertEqual(self.A.get_angle_between(self.B), 0) self.assertAlmostEqual(self.D.get_angle_between(self.A), 45)
def __init__(self, **kwargs): self.position = kwargs.get('position', PVector(0, 0, 0)) self.orientation = kwargs.get('orientation', PVector(1, 0, 0))
def __init__(self, **kwargs): self.velocity = kwargs.get('velocity', PVector(0, 0, 0)) self.mass = kwargs.get('mass', 1)
def setUp(self): self.A = PVector(1, 0) self.B = PVector(0, 5) self.C = PVector(3,4) self.D = PVector(4, 4)
def draw_poly(self): pyp.sphere(self.size) pyp.line(self.position, PVector(0, 0, 0))