def plane_reader(properties): plane = Plane() for prop in properties: prop = prop.strip() props = prop.split(' ') if props[0] == 'pos:': plane.pos = vector.vec(float(props[1]), float(props[2]), -float(props[3])) continue if props[0] == 'nor:': plane.norm = vector.vec(float(props[1]), float(props[2]), float(props[3])) continue if props[0] == 'amb:': plane.amb = vector.vec(float(props[1]), float(props[2]), float(props[3])) continue if props[0] == 'dif:': plane.dif = vector.vec(float(props[1]), float(props[2]), float(props[3])) continue if props[0] == 'spe:': plane.spe = vector.vec(float(props[1]), float(props[2]), float(props[3])) continue if props[0] == 'shi:': plane.shine = float(props[1]) / 10 return plane
def test_Line2d_tangent_and_normal(): p0 = vec(0, 0) p1 = vec(2, 1) l = Line2d(p0, p1.rotate(90)) t = l.unit_tangent() n = l.unit_normal() (l.hvplot() * t.hvplot(color='r') * n.hvplot(color='g'))
def __init__(self, x, y, game): # """Параметры: Начальное местоположение по осям X и Y Cсылка на игру, в которой находится игрок""" super().__init__() # Конструирование базового класса self.frames = ( pg.image.load("./images/ball0.png"), pg.image.load("./images/ball1.png"), pg.image.load("./images/ball2.png"), pg.image.load("./images/ball3.png"), pg.image.load("./images/ball4.png"), pg.image.load("./images/ball5.png"), pg.image.load("./images/ball6.png"), pg.image.load("./images/ball7.png") ) # Загружаем в кортеж с кадрами все изображения для анимации self.current_frame = 0 # Индекс текущего кадра анимации self.last_update = pg.time.get_ticks( ) # Время последней смены кадра; Изначально равен моменту создания игрока self.image = self.frames[ self. current_frame] # Текущее изображение из кортежа кадров по текущему индексу self.rect = self.image.get_rect() # Взятие прямоугольника self.rect.center = (x, y) # Задание координат центра self.vel = vec(0, 0) # Вектор скоростей self.acc = vec(0, 0) # Вектор ускорений self.pos = vec(x, y) # Вектор местоположения игрока self.game = game # Сохранене ссылки на игру self.on_ground = False # Изначально не на земле
def sphere_reader(properties): sphere = Sphere() for prop in properties: prop = prop.strip() props = prop.split(' ') if props[0] == 'pos:': sphere.pos = vector.vec(float(props[1]), float(props[2]), -float(props[3])) continue if props[0] == 'rad:': sphere.rad = float(props[1]) continue if props[0] == 'amb:': sphere.amb = vector.vec(float(props[1]), float(props[2]), float(props[3])) continue if props[0] == 'dif:': sphere.dif = vector.vec(float(props[1]), float(props[2]), float(props[3])) continue if props[0] == 'spe:': sphere.spe = vector.vec(float(props[1]), float(props[2]), float(props[3])) continue if props[0] == 'shi:': sphere.shine = float(props[1]) / 5 return sphere
def test_Line2d_constructor_1(): p0 = vec(0, 0) p1 = vec(2, 1) l = Line2d(p0, p1) overlay = (l.hvplot() * p0.hvplot(color='b', size=10) * p1.hvplot(color='r', size=10) * p1.rotate(90).hvplot(color='g', size=10)) display(overlay)
def areaLight(self): global lights lights.append( Light( vector.vec(self.position.x + 0.5, self.position.y + 0.5, self.position.z + 0.5), self.colour)) lights.append( Light( vector.vec(self.position.x - 0.5, self.position.y - 0.5, self.position.z - 0.5), self.colour))
def test_Line2d_get_normal_band_2(): from shapely.geometry import Polygon p0 = vec(0, 0) p1 = vec(2, 1) l = Line2d(p0, p1) band = l.get_normal_band(1) overlay = (l.hvplot() * l.unit_normal().hvplot(color='r', size=10) * hv.Polygons([Polygon(band)]).opts(alpha=0.1)) display(overlay)
def __init__(self, surface, img): pygame.sprite.Sprite.__init__(self) self.surface = surface self.image = img # rect = self.image.get_rect() # pygame.draw.rect(self.image,(0, 0, 255),(0, 0, rect.width-1,rect.height -1),1) self.rect = self.image.get_rect() self.vel = vec(0, 0) self.acc = vec(0, 0) width, height = self.surface.get_size() self.pos = vec(width / 2, height - HEIGHT - 10) self.rect.center = self.pos
def sdEquilateralTriangle(query): """ Signed distance function for a unit length equilateral triangle centered at the origin """ if len(query) != 2: raise ValueError(f"Input vector must be 2-dimensional: {len(query)}") k = 3**.5 query = vec(np.abs(query[0]) - 1.0, query[1] + 1.0/k) if query[0] + k*query[1] > 0.: query = vec(query[0] - k*query[1], -k*query[0]-query[1])/2. query[0] -= np.clip(query[0], -2., 2.) return - query.norm()*np.sign(query[1])
def __init__(self, pos=None, norm=None, amb=None, dif=None, spe=None, shine=None): self.pos = pos or vector.vec(0, 0, 0) self.norm = norm or 0 self.amb = amb or vector.vec(0, 0, 0) self.dif = dif or vector.vec(0, 0, 0) self.spe = spe or vector.vec(0, 0, 0) self.shine = shine or 0 self.bounce = 0
def light_reader(properties): global lights light = Light() for prop in properties: prop = prop.strip() props = prop.split(' ') if props[0] == 'pos:': light.position = vector.vec(float(props[1]), float(props[2]), -float(props[3])) continue if props[0] == 'col:': light.colour = vector.vec(float(props[1]), float(props[2]), float(props[3])) return light
def test_iteration_small(): N = 31 a = vec(range(N)) b = 0 for i in a: b += i assert b == N * (N - 1) / 2
def __init__(self, game): self._layer = PLAYER_LAYER self.groups = game.all_sprites pg.sprite.Sprite.__init__(self, self.groups) self.game = game self.walking = False self.jumping = False self.current_frame = 0 self.last_update = 0 self.load_images() self.image = self.standing_frames[0] self.rect = self.image.get_rect() self.rect.center = (40, HEIGHT - 100) self.pos = vec(40, HEIGHT - 100) self.vel = vec(0, 0) self.acc = vec(0, 0)
def test_count(): ll = [1, 2, 2, 3, 3, 3] shuffle(ll) a = vec(ll) assert a.count(1) == ll.count(1) assert a.count(2) == ll.count(2) assert a.count(3) == ll.count(3) assert a.count('a') == ll.count('a')
def test_cons(): # Like list.append, except returns new vector w/ structural sharing. v0 = vec() assert len(v0) == 0 v1 = v0.cons(1) assert len(v0) == 0 assert len(v1) == 1 assert v1[0] == 1
def test_cons_128(): N = 128 v = vec() for i in range(N): v = v.cons(i) assert len(v) == N for i in range(N): assert v[i] == i
def test_cons_1048576(): N = 1048576 v = vec() for i in xrange(N): v = v.cons(i) assert len(v) == N for i in xrange(N): assert v[i] == i
def test_index(): ll = range(20) shuffle(ll) v = vec(ll) for i in ll: assert ll.index(i) == v.index(i) with pytest.raises(ValueError): v.index(30)
def __mul__(self, other): if type(other) == type(self): return quat((self.s*other.s)-(self.v*other.v), (self.s*other.v)+(self.v*other.s)+(self.v^other.v)) if type(other) == type(vec(0,0,0)): return self*quat(0,other) else: return quat(other*self.s, other*self.v)
def eval_sdf(xs, ys, sdFunc): zz = np.empty( (len(ys), len(xs)) ) for j in range(len(ys)): for i in range(len(xs)): q = vec(xs[i],ys[j]) zz[j,i] = sdFunc(q) return zz
def generate_speed( self, direction): # Генерация скорости движения на основе направления if isinstance(direction, str): # Проверяем что направление - строка vel = vec(0, 0) # Заготовка вектора скорости if direction == "up": vel = vec(0, -SAW_SPEED) elif direction == "down": vel = vec(0, SAW_SPEED) elif direction == "left": vel = vec(-SAW_SPEED, 0) elif direction == "right": vel = vec(SAW_SPEED, 0) else: # Если направление не одно и четырёх, оно неверное; ValueError raise ValueError("Invalid direction") return vel # Возвращаем полученную скорость else: # Иначе TypeError raise TypeError("Direction must be str")
def check_collision(self, target): lowest_ticks = 99999 lowest_ticks_rotation = 0 if target is not None: for rotation, missile_orbit in self.own_missile_orbits.items(): for tick in range(len(missile_orbit)): if self.target_orbit[target][tick] == vec( 0, 0) or missile_orbit[tick] == vec(0, 0): continue if (self.target_orbit[target][tick] - missile_orbit[tick]).t_length() <= 0.1: ticks = tick + math.ceil(abs(rotation) / 10) if ticks < lowest_ticks: lowest_ticks = ticks lowest_ticks_rotation = rotation if lowest_ticks != 99999: return lowest_ticks, lowest_ticks_rotation else: return None, None
def test_assoc(): # TODO: FIXME: test with a big vector, bigger than 32, 32**2, 32**3, etc... a = vec(range(31)) b = a.assoc(0, 10) assert a[0] == 0 assert b[0] == 10 assert a[1] == b[1] assert a[2] == b[2] c = b.assoc(1, 5) assert c[1] == 5
def test_slice(): ll = range(20) l2 = ll[5:10] v = vec(ll) v2 = v[5:10] assert len(l2) == len(v2) for a, b in zip(l2, v2): assert a == b with pytest.raises(NotImplementedError): v[::2]
def sdStar(query, radius, n, m): """ Args: - query (vec) - radius (float) - n (int) - m (float) """ # Next 4 lines can be precomputed for a given shape an = np.pi/float(n) en = 2*np.pi/m acs = vec(np.cos(an), np.sin(an)) ecs = vec(np.cos(en), np.sin(en)) bn = np.mod(np.arctan2(*query.values), 2.0*an) - an query = query.norm() * vec(np.cos(bn), np.abs(np.sin(bn))) query = query - radius*acs query = query + ecs * np.clip(- query.inner(ecs), 0.0, radius*acs[1]/ecs[1]) return query.norm() * np.sign(query[0])
def get_movement(self, number_of_ticks): positions = [] # Initial conditions pos = self.position vel = self.velocity energy = self.energy is_dead = False for t in range(number_of_ticks): if energy <= 0 or is_dead: positions.append(vec(0, 0)) continue angle = pos.atan2() if pos.length() < 0.1: is_dead = True positions.append(vec(0,0)) continue force = pos.length() / energy vel.x -= cos(angle) * force vel.y -= sin(angle) * force if vel.x > 0.05: vel.x = 0.05 if vel.y > 0.05: vel.y = 0.05 if vel.x < -0.05: vel.x = -0.05 if vel.y < -0.05: vel.y = -0.05 pos += vel energy -= 1 if pos.x > 1.0: pos.x = -1.0 elif pos.x < -1.0: pos.x = 1.0 if pos.y > 1.0: pos.y = -1.0 elif pos.y < -1.0: pos.y = 1.0 positions.append(pos) return positions
def update(self): # Задание ускорения вначале такта self.acc = vec(0, PLAYER_GRAVITY ) # По оси Y воздействует ускорение свободного падения self.control_processing() self.physical_calculations() self.collide_processing() self.rect.center = self.pos # Перемещение изображения в местоположение игрока self.wall_processing() self.animate()
def check_collision(self, target): lowest_ticks = 99999 lowest_ticks_rotation = 0 if target is not None: for rotation, missile_orbit in self.own_missile_orbits.items(): for tick in range(len(missile_orbit)): if self.target_orbit[target][tick] == vec(0, 0) or missile_orbit[tick] == vec(0,0): continue if (self.target_orbit[target][tick] - missile_orbit[tick]).t_length() <= 0.1: ticks = tick + math.ceil(abs(rotation) / 10) if ticks < lowest_ticks: lowest_ticks = ticks lowest_ticks_rotation = rotation if lowest_ticks != 99999: return lowest_ticks, lowest_ticks_rotation else: return None, None
def move(self, label): self.acc = vec(0, 0) if label == pygame.K_LEFT: self.acc.x = -BASKET_ACC if label == pygame.K_RIGHT: self.acc.x = BASKET_ACC self.acc += self.vel * (-BASKET_FRICTION) self.vel += self.acc self.pos += (self.vel + 0.5 * self.acc) # print(self.acc, self.vel, self.pos) screenSize = self.surface.get_size() if self.pos.x < self.rect.width / 2: self.pos.x = self.rect.width / 2 if self.pos.x > screenSize[0] - self.rect.width / 2: self.pos.x = screenSize[0] - self.rect.width / 2 self.rect.center = self.pos
def camera_reader(properties): camera = Camera() for prop in properties: prop = prop.strip() props = prop.split(' ') if props[0] == 'pos:': camera.pos = vector.vec(float(props[1]), float(props[2]), (float(props[3])) - 1) continue if props[0] == 'f:': camera.focal_length = (float(props[1])) continue if props[0] == 'fov:': camera.fov = (2 * numpy.pi / 360 * float(props[1]) ) # values[0] == fov continue if props[0] == 'a:': camera.ratio = (float(props[1])) # values[1] == aspect ratio return camera
def update(self): self.animate() self.acc = vec(0, PLAYER_GRAV) keys = pg.key.get_pressed() if keys[pg.K_LEFT]: self.acc.x = -PLAYER_ACC if keys[pg.K_RIGHT]: self.acc.x = PLAYER_ACC # apply friction self.acc.x += self.vel.x * PLAYER_FRICTION # equations of motion self.vel += self.acc if abs(self.vel.x) < 0.1: self.vel.x = 0 self.pos += self.vel + 0.5 * self.acc # wrap around the sides of the screen if self.pos.x > WIDTH + self.rect.width / 2: self.pos.x = 0 - self.rect.width / 2 if self.pos.x < 0 - self.rect.width / 2: self.pos.x = WIDTH + self.rect.width / 2 self.rect.midbottom = self.pos
def test_sdLine(): q = vec(1.,0.) a = vec(0., 0.) b = vec(1.0, 0.) assert np.isclose([sdLine(q,a,b)], [0])
def test_indexing_pos(): v = vec([1, 2, 3]) assert v[0] == 1 assert v[1] == 2 assert v[2] == 3
def get_movement(self, number_of_ticks): positions = [] # Initial conditions pos = self.position vel = self.velocity energy = self.energy rotation = self.rotation is_dead = False for t in range(number_of_ticks): if is_dead: positions.append(vec(0, 0)) continue elif pos.length() < 0.1: is_dead = True positions.append(vec(0, 0)) continue if vel.length() > MISSILE_MAX_SPEED: velocityAngle = vel.atan2() vel.x = cos(velocityAngle) * MISSILE_MAX_SPEED vel.y = sin(velocityAngle) * MISSILE_MAX_SPEED # Force only depends on distance from the sun force = pos.length() / 1000 angle = pos.atan2() vel.x -= cos(angle) * force vel.y -= sin(angle) * force pos += vel if pos.x > 1.0: pos.x = -1.0 elif pos.x < -1.0: pos.x = 1.0 if pos.y > 1.0: pos.y = -1.0 elif pos.y < -1.0: pos.y = 1.0 positions.append(pos) # Always point in the right direction if self.type == "NORMAL": rotation = vel.atan2() # Might be a bug. Logically, this should be before pos+=vel if energy < 10: vel /= 1.01 continue if self.type == "MINE": vel.x += cos(rotation) * 0.0005 vel.y += sin(rotation) * 0.0005 energy -= 1 continue energy -= 50 if self.type == "NORMAL": vel.x += cos(rotation) * (energy / 1000000.0) vel.y += sin(rotation) * (energy / 1000000.0) elif self.type == "SEEKING": vel.x += cos(rotation) * (energy / 100000.0) vel.y += sin(rotation) * (energy / 100000.0) return positions
def test_sdCircle(): q = vec(1.,0.) r = 1 assert np.isclose([sdCircle(q,r)], [0])
def update(self, data): self.position = vec(data['x'], data['y']) self.velocity = vec(data['velocityX'], data['velocityY']) self.rotation = data['rotation'] self.energy = data['energy']
def test_creation_empty(): v = vec() assert len(v) == 0 w = vec([]) assert len(w) == 0
def test_creation_non_empty(): v = vec([1, 2, 3]) assert len(v) == 3
def test_iteration_empty(): a = vec() for i in a: assert False
def test_containment(): N = 20 a = vec(range(N)) for i in range(N): assert i in a assert 100 not in a
def __init__(self, position=None, colour=None): self.position = position or vector.vec(0, 0, 0) self.colour = colour or vector.vec(0, 0, 0)
def test_sdTriangle(): q = vec(0.,-1.) v0, v1, v2 = vec(0,0), vec(1,0), vec(0.5, 0.5) assert np.isclose( [sdTriangle(q, v0, v1, v2)], [-1.])
def __init__(self, focal_length=None, fov=None, pos=None, ratio=None): self.focal_length = focal_length or 1000 self.fov = fov or 60 self.pos = pos or vector.vec(0, 0, -1) self.ratio = ratio or 1
def __getitem__(self, item): return vector.vec(self.data[item])
scene = list() camera = Camera() scene = scene_reader('scene5.txt') infinity = 1.30e59 (WIDTH, HEIGHT) = (2 * camera.focal_length * numpy.tan(camera.fov / 2) * camera.ratio, (2 * camera.focal_length * numpy.tan(camera.fov / 2))) print(lights) lightlen = len(lights) for light in lights: light.areaLight() if len(lights) == 3 * lightlen: break #lights.append(Light(vector.vec(1,0,1), vector.vec(0.9, 0., .2))) # Screen coordinates: x0, y0, x1, y1. S = (-camera.ratio * numpy.tan(camera.fov / 2), numpy.tan(camera.fov / 2) + 0.25, camera.ratio * numpy.tan(camera.fov / 2), -numpy.tan(camera.fov / 2) + 0.25) x = numpy.tile(numpy.linspace(S[0], S[2], int(WIDTH)), int(HEIGHT)) y = numpy.repeat(numpy.linspace(S[1], S[3], int(HEIGHT)), int(WIDTH)) Q = vector.vec(x, y, 0.) color = raytrace(camera.pos, (Q - camera.pos).normal(), 0, scene) rgb = [ Image.fromarray((255 * numpy.clip(c, 0, 1).reshape( (int(HEIGHT), int(WIDTH)))).astype(numpy.uint8), "L") for c in color.components() ] Image.merge("RGB", rgb).save("fig.bmp")