def __init__(self, x, y, data): self.data = data if len(data) > 0: self.columns = len(data[0]) self.rows = len(data) else: self.columns = 0 self.rows = 0 height_p = self.rows * 3 self.top = Window.size[1] * y / 100 self.bot = Window.size[1] * (y - height_p) / 100 self.height = self.top - self.bot width_p = 5 * self.columns self.left = Window.size[0] * x / 100 self.right = Window.size[0] * (x + width_p) / 100 self.width = self.right - self.left self.lines = { "top": LineInfo(Vector(self.left, self.top, self.right, self.top)), "bot": LineInfo(Vector(self.left, self.bot, self.right, self.bot)), "right": LineInfo(Vector(self.right, self.top, self.right, self.bot)), "left": LineInfo(Vector(self.left, self.top, self.left, self.bot)) }
class ZONE: dims = Vector(0.54 * M, 0.48 * M) outlines = ( # F1, F4, F2, F5, F3, F6 *mirrors(Box(dims, Vector(-3.54 * M, 0.55 * M))), *mirrors(Box(dims, Vector(-2.14 * M, -0.59 * M))), *mirrors(Box(dims, Vector(0, 1.795 * M))) )
def get_obstacle_tangent_field(self, mytank, obj, r, s, b): d_edges, a_edges = self.__get_line_distances(mytank, obj) d_points = self.__get_point_distances(mytank, obj) d_close_edge = min(d_edges[0], d_edges[1], d_edges[2], d_edges[3]) d_close_point = min(d_points[0], d_points[1], d_points[2], d_points[3]) theta = a_edges[d_edges.index(d_close_edge)] #distance b/w line and point is perpendicular unless distance is to a corner if d_close_point == d_close_edge: corner = d_points.index(d_close_point) #theta = get_angle(mytank, Point(obj[corner])) #theta = theta pi/2.0 #to make tangential dx = 0 dy = 0 if d_close_edge < r: dx = -sign(cos(theta))*float('inf') dy = -sign(sin(theta))*float('inf') elif d_close_edge >= r and d_close_edge <= s+r: dx = -b * (s + r - d_close_edge) * cos(theta) dy = -b * (s + r - d_close_edge) * sin(theta) vector = Vector() vector.set_x_and_y(dx, dy) return vector
def update(self, delta, game): self.time += delta self.position = self.position.translate(self.velocity * (delta / 1000.0)) self.velocity = self.velocity + self.up_direction( ) * constants.PLAYER_JUMP_ACCELERATION * (delta / 1000.0) if self.on_ground(): self.position = self.meteor_model.position.translate( self.up_direction() * (self.meteor_model.radius + constants.PLAYER_HEIGHT / 2)) self.velocity = Vector(0, 0) self.can_switch = True self.adjust_rotation(delta) if self.can_switch: def meteor_model_key(meteor_model): return meteor_model.get_height(self.position) new_meteor_model = min(game.meteor_models, key=meteor_model_key) if new_meteor_model != self.meteor_model: self.meteor_model = new_meteor_model self.can_switch = False self.moved = ((self.last_position - self.position).length() > 0.01) self.last_position = self.position self.notify()
def get_obstacle_tangent_field(self, mytank, obj, r, s, b): d_edges, a_edges = self.__get_line_distances(mytank, obj) d_points = self.__get_point_distances(mytank, obj) d_close_edge = min(d_edges[0], d_edges[1], d_edges[2], d_edges[3]) d_close_point = min(d_points[0], d_points[1], d_points[2], d_points[3]) theta = a_edges[d_edges.index( d_close_edge )] #distance b/w line and point is perpendicular unless distance is to a corner if d_close_point == d_close_edge: corner = d_points.index(d_close_point) #theta = get_angle(mytank, Point(obj[corner])) #theta = theta pi/2.0 #to make tangential dx = 0 dy = 0 if d_close_edge < r: dx = -sign(cos(theta)) * float('inf') dy = -sign(sin(theta)) * float('inf') elif d_close_edge >= r and d_close_edge <= s + r: dx = -b * (s + r - d_close_edge) * cos(theta) dy = -b * (s + r - d_close_edge) * sin(theta) vector = Vector() vector.set_x_and_y(dx, dy) return vector
def signed_distance_bound(self, p): v = self.value(p) if v == 0: return 0 elif v < 0: # if inside the ellipse, create an inscribed quadrilateral # that contains the given point and use the minimum distance # from the point to the quadrilateral as a bound. Since # the quadrilateral lies entirely inside the ellipse, the # distance from the point to the ellipse must be smaller. v0, v2 = self.intersections(p, p + Vector(1, 0)) v1, v3 = self.intersections(p, p + Vector(0, 1)) return abs(ConvexPoly([v0, v1, v2, v3]).signed_distance_bound(p)) else: c = self.center crossings = self.intersections(c, p) # the surface point we want is the one closest to p if (p - crossings[0]).length() < (p - crossings[1]).length(): surface_pt = crossings[0] else: surface_pt = crossings[1] # n is the normal at surface_pt n = self.gradient * surface_pt n = n * (1.0 / n.length()) # returns the length of the projection of p - surface_pt # along the normal return -abs(n.dot(p - surface_pt))
def link(self, indexed_nodes): left = indexed_nodes[self.position + Vector(-1, 0)] right = indexed_nodes[self.position + Vector(1, 0)] up = indexed_nodes[self.position + Vector(0, -1)] down = indexed_nodes[self.position + Vector(0, 1)] self.neighborhood = {left, right, up, down} - {None}
def handle_collision(self, collision): self.circle.pos = collision.point if collision.kind == objects.wall: self.v.x = -self.v.x elif collision.kind == objects.floor: if self.circle.pos[0] < window_width / 2: self.parent.add_goal(0) else: self.parent.add_goal(1) return (True, self.parent.stop()) elif collision.kind == objects.plate: self.v.y = -self.v.y elif collision.kind == objects.node: half = self.parent.halves[collision.node_id] node_pos = half.node.pos speed = self.v.speed() self.v = Vector(begin=node_pos, end=self.circle.pos) self.v.normalize() self.v *= speed self.v += half.vector self.v *= spring_ability return (False, False)
def on_tick(self): # Get the board vector board = self.board_vector().vect # Calculate the new direction player = self.player_vector().vect new_dir = board.transform(player) #You can not go backwards if new_dir.y < 0: new_dir.y = 0 # You can only go a certain speed # and you are slowed down if above a certain speed vector = Vector(Point(0,0), new_dir) #scale = -1 if vector.length() > self.break_speed: scale = float(vector.length()) - self.slowed new_dir = vector.scale_absolute(scale).vect if vector.length() > self.max_speed: # Jitter player change = random.uniform(-self.jitter, self.jitter) # * vector.length() / self.max_speed if abs(self.player + change) < self.max_lean: self.player += change new_pos = self.position.transform(new_dir) self.direction = new_dir self.position = new_pos
def __init__(self, t, pos, velocity, universe, onHit, onOutOfRect, max_len=Config.maxTrajectoryLength, max_err=Config.maxTrajectoryError): ObjectPath.__init__(self, t) self.universe = universe self.startPos = pos.copy() self.max_len = max_len self.max_err = max_err self.onOutOfRect = onOutOfRect self.onHit = onHit self.min_seg_len = Config.minPolySegmentLength self.max_seg_len = Config.maxPolySegmentLength # min_seg_len is the different to min_seg_calc: # one is the minimum segment length, we (eventually) # store in the array. # the other (min_seg_calc) is the the minimum segment, we use # to calculate the trajectory. self.min_seg_calc = self.min_seg_len / 10 # Cumulative error self.cumError = 0 # some little extra to take rounding errors into account arrSize = int(self.max_len / self.min_seg_len * 1.05) # The first array contains the time values, # the second one contains the the positions, veocities and path lengths # Why two arrays? # Because np.searchSorted() only works on 1-dimensional arrays. self.timeBuffer = np.zeros(arrSize, dtype=np.double) self.segBuffer = np.zeros((arrSize, 5), dtype=np.double) self.timeBuffer[0] = t # (xPos, yPos, xVel, yVel, path length) self.segBuffer[0] = (pos.x, pos.y, velocity.x, velocity.y, 0) # Time and segment arrays # Note that numpy slices are *views* for the underlying array, # no data is copied here. self.segments = self.segBuffer[:1] self.time = self.timeBuffer[:1] self.state = TrajectoryState(t, self.segments[0]) self.state2 = TrajectoryState(t, self.segments[0]) self.calculatedSegments = 0 # Buffers to reduce amount of allocated Vector objects self.tmpVec1 = Vector(0, 0) self.tmpVec2 = Vector(0, 0) self.tmpVec3 = Vector(0, 0) self.tmpVec4 = Vector(0, 0)
def test_intersection_1(): l1 = Line() # X axis l2 = Line(direction_vector=Vector([0, 1, 0]), point=Point(0, 1, 0)) # Y-axis l3 = Line(direction_vector=Vector([-1, 1, 0]), point=Point(3, 0, 0)) assert l1.intersection(l2) == Point(0, 0, 0) assert l3.intersection(l2) == Point(0, 3, 0)
def update(self, dt): bps = self.battle_preparing if bps.active: bps.energy += 6 * dt completed_move = [] for actor, (x, y, velocity) in self.moving_sprites.items(): current_pos = Vector(actor.sprite.x, actor.sprite.y) destination = Vector(x, y) if (destination - current_pos).magnitude_squared < 0.1: actor.sprite.update(*self.coords_to_pixels(actor.x, actor.y)) completed_move.append(actor) else: current_pos = ((current_pos * (5 - 1)) + destination) / 5 actor.sprite.update(current_pos.x, current_pos.y) completed_rotation = [] for actor, (angle, speed) in self.rotating_sprites.items(): if abs(actor.sprite.rotation - angle) < 1: actor.sprite.update(rotation=angle) completed_rotation.append(actor) else: actor.sprite.update(rotation=((actor.sprite.rotation * (speed - 1)) + angle) / speed) for sprite in completed_move: del self.moving_sprites[sprite] for sprite in completed_rotation: del self.rotating_sprites[sprite]
def refresh(self): for obj in self.parent.blocks: if obj.lives == 0: continue if self.intersect_with_react(obj): obj.hit() if self.parent.debug: self.parent.debug_line( self.x + self.radius, self.y + self.radius, self.x + 25 * self.speed_x + self.radius, self.y + 25 * self.speed_y + self.radius ) break # panel if self.intersect_with_react(self.parent.panel): self.y += self.speed_y self.x += self.speed_x speed = self.parent.panel.speed_x if speed != 0: ball_speed_vec = Vector(self.speed_x, self.speed_y) rotate_angle = random.randint(1, 15) ball_speed_vec = ball_speed_vec.rotate( speed / 3 * rotate_angle ) self.speed_x = ball_speed_vec.x self.speed_y = ball_speed_vec.y if self.y + self.speed_y + 2 * self.radius > self.parent.HEIGHT: self.parent.lose_ball() # super refreshing super().refresh()
def __init__(self, name): super(VectorSprite, self).__init__(name) self.vector = Vector(name, 0, 0) self.vector_origin = 0, 0 self.draw_width = 5 self.draw_color = 255, 255, 255
def __init__(self, is_one: bool, team: Team): self.is_one = is_one self.team = team self.center = FIELD.spawn_center.mirror(team.is_blue, team.is_blue == is_one) self.rotation = 0. if team.is_blue else math.pi self.gimbal_yaw = 0. self.speed = Vector(0., 0.) self.rotation_speed = 0. self.gimbal_yaw_speed = 0. self.ammo = 50 if is_one else 0 self.is_shooting = False self.shot_cooldown = 0 self.heat = 0 self.hp = 2000 self.barrier_hits = 0 self.robot_hits = 0 self.can_move = True self.can_shoot = True self.debuff_timeout = 0 self._corners = [ c.transform(self.center, self.rotation) for c in ROBOT.outline.corners ] self._armor_lines = [ a.transform(self.center, self.rotation) for a in ROBOT.armor_lines ]
def Rectangle(v1, v2, color=None): return Quad([ Vector(min(v1.x, v2.x), min(v1.y, v2.y)), Vector(max(v1.x, v2.x), min(v1.y, v2.y)), Vector(max(v1.x, v2.x), max(v1.y, v2.y)), Vector(min(v1.x, v2.x), max(v1.y, v2.y)) ], color=color)
def __str__(self): if self.direction == Vector(1, 0): return '=' if self.broken else '>' elif self.direction == Vector(-1, 0): return '=' if self.broken else '<' elif self.direction == Vector(0, 1): return '¦' if self.broken else 'v' elif self.direction == Vector(0, -1): return '¦' if self.broken else '^'
def testGeometry(): print 'testing geometry...', vec1 = Vector(1, 2, 3) vec2 = Vector(-2, 4, 5) assert vec1 + vec2 == Vector(-1, 6, 8) assert vec1**vec2 == -2 + 8 + 15 assert vec1 * vec2 == -1 * (vec2 * vec1) assert vec1 * -1 == Vector(-1, -2, -3) print 'passed!'
def test_orthogonal(): l1 = Line() # X-axis l2 = Line(direction_vector=Vector([0, 1, 0]), point=Point(0, 0, 0)) # Y-axis l3 = Line(direction_vector=Vector([1, 1, 0]), point=Point(0, 0, 0)) l4 = Line(direction_vector=Vector([0, 0, 1]), point=Point(0, 0, 0)) assert l1.is_orthogonal(l2) assert l3.is_orthogonal(l4) assert not l1.is_orthogonal(l3)
def _line(self, pieces, line): if len(pieces) != 7: raise PartError, "Invalid line data in %s at line %i" % (self.path, line) colour = int(pieces[0]) p1 = map(float, pieces[1:4]) p2 = map(float, pieces[4:7]) return Line(Colour(colour), Vector(*p1), Vector(*p2))
def test_arithmetics(a): """add and mul""" assert a + a == 2.0 * a """sub""" assert a - a == Vector(0.0, 0.0, 0.0) """div and truediv""" assert a / 2.0 == Vector(0.5, 0.5, 0.5) """pow""" """neg""" assert -a == Vector(-1.0, -1.0, -1.0)
def pump(self): if not self.pump_blocked: self.pump_blocked = True dir_vect = Vector(Point(0,0), self.direction) velocity = dir_vect.length() pump = self.pump_efficiency() * self.max_pump self.direction = dir_vect.scale_absolute(velocity + pump).vect
def test_rotate(): axis = Vector(0.0, 0.0, 1.0) angle = np.deg2rad(-90.0) quat = Quat.from_angle_and_axis(angle, axis) vector = Vector(0.0, 5.0, 0.0) rotated = Vector(5.0, 0.0, 0.0) assert(quat.rotate(vector) == rotated) assert(vector.rotate(quat) == rotated)
def _triangle(self, pieces, line): if len(pieces) != 10: raise PartError, "Invalid triangle data in %s at line %i" % (self.path, line) colour = int(pieces[0]) p1 = map(float, pieces[1:4]) p2 = map(float, pieces[4:7]) p3 = map(float, pieces[7:10]) return Triangle(Colour(colour), Vector(*p1), Vector(*p2), Vector(*p3))
def __init__(self, entity): self.entity = entity self.mass = 1 self.elasticity = 1 self.gravity = 0 self.friction = .75 self.velocity = Vector(entity.name + " velocity", 0, 0) self.forces = [] self.last_position = 0, 0
def renew_crd(theta, id): # координаты axis1 = Vector(frame[id], frame[id + 1]) / Vector(frame[id], frame[id + 1]).len() for i in range(index[id + 2], len(crd), 1): old = Vector(crd[index[id]]) v = Vector(crd[index[id]], crd[i]) new = v * theta.cos - vmul( axis1, v) * theta.sin + axis1 * (axis1 * v) * (1 - theta.cos) crd[i] = (new + old).to_point()
def constructNormalRec(start_pt_lst, length, width): start_pt = Point2D(start_pt_lst) vec_lst = [] length_vec = Vector(length, 0.0) width_vec = Vector(0.0, width) vec_lst = [length_vec, width_vec, ReverseVector(length_vec), ReverseVector(width_vec)] rec = Rectangle(vec_lst, start_pt) #print("print(rec.vec_lst): ") #for vec in rec.vec_lst: # print(vec) return rec
def test_vector_antiparallel(): v1 = Vector([1, 1, 1]) v2 = Vector([-1, -1, -1]) v3 = Vector([0, 0, 1]) assert v1.is_antiparallel(v2) assert not v2.is_antiparallel(v3) assert not v3.is_antiparallel(v1)
def test_vector_parallel(): v1 = Vector([1, 1, 1]) v2 = Vector([3, 3, 3]) v3 = Vector([0, 1, 0]) assert v1.is_parallel(v2) assert not v2.is_parallel(v3) assert not v3.is_parallel(v1)
def test_line_generation(): Line() Line(direction_vector=Vector([1, 1, 1]), point=Point(2, 2, 2)) with pytest.raises(TypeError): Line(direction_vector=Point(1, 1, 1)) with pytest.raises(ValueError): Line(direction_vector=Vector([0, 0, 0])) Line.from_points(Point(1, 1, 1), Point(2, 2, 2))
def renew_len(): for i in range(len(crd) - 1): for bond in bond_length[i]: if i < bond[0]: v = Vector(crd[i], crd[bond[0]]) k = bond[1] / v.len() tmp = crd[bond[0]] crd[bond[0]] = crd[i] + (v * k) for l in range(bond[0] + 1, len(crd)): v = Vector(tmp, crd[l]) tmp = crd[l] crd[l] = crd[l - 1] + v
def _optional_line(self, pieces, line): if len(pieces) != 13: raise PartError, "Invalid line data in %s at line %i" % (self.path, line) colour = int(pieces[0]) p1 = map(float, pieces[1:4]) p2 = map(float, pieces[4:7]) p3 = map(float, pieces[7:10]) p4 = map(float, pieces[10:13]) return OptionalLine(Colour(colour), Vector(*p1), Vector(*p2), Vector(*p3), Vector(*p4))
def __init__(self, meteor_model, position): GameObjectModel.__init__(self, position) self.meteor_model = meteor_model self.rotation = self.target_angle() self.velocity = Vector(0, 0) self.can_switch = True self.last_position = self.position self.moved = False self.last_direction = "right" self.time = 0
def _quadrilateral(self, pieces, line): if len(pieces) != 13: raise PartError, "Invalid quadrilateral data in %s at line %i" % (self.path, line) colour = int(pieces[0]) p1 = map(float, pieces[1:4]) p2 = map(float, pieces[4:7]) p3 = map(float, pieces[7:10]) p4 = map(float, pieces[10:13]) return Quadrilateral(Colour(colour), Vector(*p1), Vector(*p2), Vector(*p3), Vector(*p4))
def test_angle(): a = Vector(1,0,1) b = Vector(1,0,0) A = np.array(a) B = np.array(b) # Test for single vector pair assert(angle(A,B) == a.angle(b)) AA = np.tile(A, (10,5,1)) BB = np.tile(B, (10,5,1)) # Test at higher-dimensions assert(np.all( angle(AA,BB) == a.angle(b) ))
def __init__(self, ps, color=None): Shape.__init__(self, color) mn = min(enumerate(ps), key=lambda (i,v): (v.y, v.x))[0] self.vs = list(ps[mn:]) + list(ps[:mn]) self.bound = Vector.union(*self.vs) self.half_planes = [] for i in xrange(len(self.vs)): h = HalfPlane(self.vs[i], self.vs[(i+1) % len(self.vs)]) self.half_planes.append(h)
def get_attract_field(self, mytank, obj, r, s, a): d = get_center_distance(mytank, obj) theta = get_angle(mytank, obj) dx = 0; dy = 0 if d > (s+r): dx = a * s * cos(theta) dy = a * s * sin(theta) elif d >= r: #and d<=s+r dx = a * (d-r) * cos(theta) dy = a * (d-r) * sin(theta) #else dx = 0 dy = 0 vector = Vector() vector.set_x_and_y(dx, dy) return vector
def get_repulse_field(self, mytank, obj, r, s, b): d = get_center_distance(mytank, obj) theta = get_angle(mytank, obj) dx = 0 dy = 0 if d < r: dx = -sign(cos(theta))*float('inf') dy = -sign(sin(theta))*float('inf') elif d >= r and d <= s+r: dx = -b * (s + r - d) * cos(theta) dy = -b * (s + r - d) * sin(theta) #else dx, dy = 0 vector = Vector() vector.set_x_and_y(dx, dy) return vector
def signed_distance_bound(self, p): def sgn(x): return 0 if x == 0 else x / abs(x) v = -sgn(self.value(p)) c = self.center pc = p - c u2 = self.a*pc.x**2 + self.b*pc.y**2 + self.c*pc.x*pc.y u1 = 2*self.a*c.x*pc.x + 2*self.b*c.y*pc.y \ + self.c*c.y*pc.x + self.c*c.x*pc.y + self.d*pc.x \ + self.e*pc.y u0 = self.a*c.x**2 + self.b*c.y**2 + self.c*c.x*c.y \ + self.d*c.x + self.e*c.y + self.f sols = quadratic(u2, u1, u0) crossings = c+pc*sols[0], c+pc*sols[1] if (p - crossings[0]).length() < (p - crossings[1]).length(): surface_pt = crossings[0] else: surface_pt = crossings[1] d = Vector(2*self.a*surface_pt.x + self.c*surface_pt.y + self.d, 2*self.b*surface_pt.y + self.c*surface_pt.x + self.e) return v * abs(d.dot(p - surface_pt) / d.length())
def pump_efficiency(self): dir_vect = Vector(Point(0,0), self.direction) velocity = dir_vect.length() # Scale pumping (best pumping in curve at optimal pumping speed) # check how vertical board is & scale to 0-1 verticality = 1 - ( abs(self.direction.x) / velocity ) # Check how much the player is leaning outwards scaled 0-1 leaning = abs(self.player) / self.max_lean # Check the speed (is scaled according to normal distributed # around an optimal speed ) # This is achieved using the probability density function of the normal distribution expo = (velocity - self.optimal_velocity)**2 / (2 * self.sigma**2) speed = 1 / (math.sqrt(2 * math.pi * self.sigma**2)) speed *= math.exp(-expo) # Scale the speed (value = 1 @ optimal velocity): speed /= self.pump_scale return leaning * speed # * verticality
def __init__(self, a=1.0, b=1.0, c=0.0, d=0.0, e=0.0, f=-1.0, color=None): Shape.__init__(self, color) self.a = a self.b = b self.c = c self.d = d self.e = e self.f = f t = Transform(2 * a, c, 0, c, 2 * b, 0) self.center = t.inverse() * Vector(-d, -e) l1, l0 = quadratic(1, 2 * (-a - b), 4 * a * b - c * c) v = t.eigv() axes = [v[0] * ((l0 / 2) ** -0.5), v[1] * ((l1 / 2) ** -0.5)] self.bound = Vector.union(self.center - axes[0] - axes[1], self.center - axes[0] + axes[1], self.center + axes[0] - axes[1], self.center + axes[0] + axes[1])
def check_collision(self): board = self.board_vector() # Check collision of board with wall found = False if board.p1.x < 0: self.board.position.x = 0 found = True elif board.p1.x > self.size[0]: self.board.position.x = self.size[0] found = True if found: vector = Vector(Point(0,0), self.board.direction) self.board.direction = vector.scale_absolute(3).vect return # Check collision of board with any obstacle found = False vector = Vector(Point(0,0), self.board.direction) cur = self.board.currently_on for ob in self.obstacles: if ob.check_collision(board.p1): if type(ob) == CircularObstacle: if cur == id(ob): break cur = self.board.speed() breaking = 1 - (ob.speed / 100) if cur * breaking > self.board.break_speed: self.board.direction = vector.scale_relative(breaking).vect self.board.currently_on = id(ob) break elif type(ob) == Boost: if cur == id(ob): break speed = 1 + float(ob.speed)/100 if self.board.speed() * speed <= self.board.max_speed * 1.03: self.board.direction = vector.scale_relative(speed).vect self.board.currently_on = id(ob) break elif type(ob) == Rectangular: if cur == id(ob): break self.board.direction = vector.scale_absolute(1).vect self.board.currently_on = id(ob) break else: self.board.currently_on = False
def largeArray(n=8, d=10, wid=.27, kinds=["LINEAR", "QBEZIER", "CBEZIER", "CIRCULAR", "MONOCIRCULAR"]): font = TTF("/Users/I/Desktop/diamondGDS/fonts/VeraMono.ttf") # font = TTF("/Users/I/Desktop/diamondGDS/fonts/courier-bold.ttf") toReturn = Shape([]) v = Vector(0,0) dv = Vector(n*d*2) basedir = Vector(0,1) c0 = Connection(v.copy(), -basedir.copy(), wid) c1 = Connection(v.copy(), basedir.copy(), wid) # c0.dir = basedir # # c0.wid = wid # c1.wid = wid # for kind in kinds: for i in range(0,n+1): c1.v = basedir.rotate(i*math.pi/n)*(d) for j in range(0,2*n): print "\n0x" + ("%X" % i) + ("%X" % j) c1.dir = basedir.rotate(j*math.pi/n) # print c0, c1 # (c0 + Vector(d*i*1.5, d*j*1.5) + v).plot() # (c1 + Vector(d*i*1.5, d*j*1.5) + v).plot() polyline = connectAndThicken(c0, c1, kind) if isinstance(polyline, Polyline): toReturn.add(polyline + (Vector(d*i*1.5, d*j*1.5) + v)) toReturn.add(font.shapeFromStringBoundedCentered(("%X" % i) + ("%X" % j), w=0, h=2) + (Vector(d*i*1.5, d*j*1.5) + v + Vector(3,3))) toReturn.add(font.shapeFromStringBoundedCentered(kind, w=0, h=10) + (Vector(d*n*.75, -25) + v)) v += dv return toReturn
#pixel center in space p = self.c + px * self.u_x + py * self.u_y #direction vector if self._orth: u = self.direction else: u = (p - self.position) / norm(p - self.position) yield Ray(p, u) yield None #next row if __name__ == '__main__': import pixmap s = objects.Sphere(Vector(0,0,0), 2) cpos = Vector(0, 0, 6) u = Vector.normalize(0, 0, -1) c = Camera(cpos, u, scale=0.25) image = [] l, h = 2**20, 0 for r in c.rays(): if r is not None: if s.intersects(r): col = s.intersectionDistance(r) if col > h: h = col if col < l: l = col image += [col] else: image += [-1] else:
def dev2D(tip=2, tipwid=2, diskspacing=12, electspacing=5, gap=6, groundoffset=2.5, electwid=8, wirewid=6, wirespaceF=10, wirewidF=10, gespace=40, padsize=100, disks=[1.2, 1.3, 1.4, 1.5], couplinggap=.08, couplingwid=.12, couplinglen=1, lrpad=0): toReturn = Shape([]); if diskspacing < electwid: return None numdisks = len(disks) electspacing = diskspacing/3. groundoffset = diskspacing/4. electwid = 2*diskspacing/3. wirewid = diskspacing/2. wirespace = diskspacing/2. gespace = 4.5*electwid if wirespace >= wirespaceF: wirespaceF = wirespace #+.001 if wirewid >= wirewidF: wirewidF = wirewid #+.001 v1 = Vector(math.cos(math.pi/2.+couplinglen/2.), math.sin(math.pi/2.+couplinglen/2.)) v2 = Vector(math.cos(math.pi/2.-couplinglen/2.), math.sin(math.pi/2.-couplinglen/2.)) prevConnection = 0 tranlen = .75 disky = wirewidF + wirespaceF/2. + groundoffset gapStuff = Shape([]); for i in range(0, numdisks): c = Vector((i+.5-numdisks/2.)*diskspacing, disky) gapStuff.add(circle(c, disks[i]/2.).setMaterial(1)) irad = disks[i]/2. + couplinggap orad = disks[i]/2. + couplinggap + couplingwid iwid = couplingwid owid = .24 mrad = (irad + orad)/2. # pline = arc(c, c+v1, c+v2) pline = arc(c, c+v1*irad, c+v2*irad) + arc(c, c+v2*orad, c+v1*orad) pline.closed = True gapStuff.add(pline.setMaterial(1)) left = thickenPolyline(Polyline([c+v1*mrad, c+v1*mrad+v1.perp()*tranlen]), "CUBIC", [iwid, owid]).setMaterial(1) right = thickenPolyline(Polyline([c+v2*mrad, c+v2*mrad+v2.perp().perp().perp()*tranlen]), "CUBIC", [iwid, owid]).setMaterial(1) gapStuff.add(left) gapStuff.add(right) # print 'L: ', left.connections # print 'R: ', right.connections if not isinstance(prevConnection, Connection): firstConnection = Connection(c+v1*mrad+v1.perp()*tranlen, v1.perp(), owid) else: i = prevConnection f = Connection(c+v1*mrad+v1.perp()*tranlen, v1.perp(), owid) gapStuff.add(connectAndThicken(i,f).setMaterial(1)) prevConnection = Connection(c+v2*mrad+v2.perp().perp().perp()*tranlen, v2.perp().perp().perp(), owid) gratingOne = Connection(Vector(-numdisks*diskspacing/2. - diskspacing/2., disky), Vector(1,0), owid) gratingTwo = Connection(Vector(-numdisks*diskspacing/2. - diskspacing/2. - 9.5 - 5, disky - 9.5), Vector(0,-1), owid) gratingTwoA = Connection(Vector(-(numdisks+2)*diskspacing/2., wirewidF/6.), Vector(1,0), owid) gratingTwoC = Connection(Vector(numdisks*diskspacing/2., wirewidF/6.), Vector(1,0), owid) gapStuff.add(connectAndThicken(gratingOne,firstConnection).setMaterial(1)) gapStuff.add(connectAndThicken(gratingTwoC,prevConnection).setMaterial(1)) gapStuff.add(connectAndThicken(-gratingTwoC,gratingTwoA).setMaterial(1)) gapStuff.add(connectAndThicken(-gratingTwoA,gratingTwo).setMaterial(1)) gapStuff.add(gratingMike(gratingOne)) gapStuff.add(gratingMike(gratingTwo)) # gapStuff.plot(); # arc(c, c+v1, c+v2).plot() y = gespace/4. # electspacing - groundoffset + electwid/2. -wirewid/2 + tipwid/2. for i in range(0, (numdisks+2)/2): v = Vector((i-numdisks/2.)*diskspacing, electspacing - groundoffset + electwid/2. + disky) # if i == 0: # rect1 = rect(v + Vector(0, -wirewid/2. + tipwid/2.), v + Vector(-10, wirewid/2. + tipwid/2.)) # rect1 = rect(v + Vector(wirewid/2., -wirewid/2. + tipwid/2.), v + Vector(-electwid, wirewidF-wirewid/2. + tipwid/2.)) # else: rect1 = -rect(v + Vector(-wirewid/2., -wirewid/2 + tipwid/2.), v + Vector(wirewid/2, y + wirewidF - (electspacing - groundoffset + electwid/2.))) if tip == 0: # SQUARE tipobj = rect(v - Vector(electwid/2., electwid/2.), v + Vector(electwid/2., electwid/2.)).union(-rect1).setMaterial(3) elif tip == 1: # POINTY x = electwid/2. - tipwid/2. if i == 0: pline = Polyline([v, v + Vector(x,-x)]) tipobj = rect1.union(-thickenPolyline(pline, "CONSTANT", tipwid/2., "SHARP", "ROUND")).setMaterial(3) else: pline = Polyline([v + Vector(-x,-x), v, v + Vector(x,-x)]) tipobj = thickenPolyline(pline, "CONSTANT", tipwid/2., "SHARP", "ROUND").union(-rect1).setMaterial(3) elif tip == 2: # CIRCLE tipobj = circle(v, electwid/2.).union(rect1).setMaterial(3) if i != (numdisks+2)/2.: toReturn.add(tipobj) # Pads # v = Vector(-padsize-wirespaceF/2., y + 2*wirespaceF + wirewidF + padsize) # Right # toReturn.add(rect(v, v + Vector(padsize, padsize))) # toReturn.add(rect(v + Vector(padsize-wirewidF, -padsize + wirewidF + wirespaceF), v + Vector(padsize, 0))) # toReturn.add(rect(Vector((2-numdisks/2.)*diskspacing - wirewid/2., gespace/2. + wirewidF), Vector((2-numdisks/2.)*diskspacing + wirewid/2., gespace/2. + 2*wirewidF + 2*wirespaceF))) # toReturn.add(rect(Vector((2-numdisks/2.)*diskspacing + wirewid/2., gespace/2. + 2*wirewidF + 2*wirespaceF), v + Vector(padsize-wirewidF, -padsize + wirewidF + wirespaceF))) v = Vector(-padsize-wirespaceF-wirewidF/2., y + wirespaceF + wirewidF + disky) # L/R (prev Middle) toReturn.add(rect(v, v + Vector(padsize, padsize))) toReturn.add(rect(Vector((1-numdisks/2.)*diskspacing - wirewid/2., y + disky + wirewidF), Vector((1-numdisks/2.)*diskspacing + wirewid/2., y + disky + wirewidF + wirespaceF))) toReturn.add(rect(v + Vector(padsize, 0), Vector((1-numdisks/2.)*diskspacing + wirewid/2., y + disky + 2*wirewidF + wirespaceF))) toReturn.add(rect(v - Vector(wirespaceF, wirewidF + wirespaceF), Vector((0-numdisks/2.)*diskspacing - wirewid/2., y + disky + wirewidF))) # v = Vector(-2*padsize-5*wirespaceF/2.-wirewidF, y) # Left ## toReturn.add(rect(v, v + Vector(padsize, padsize))) # toReturn.add(rect(v + Vector(padsize, 0), Vector((-numdisks/2.)*diskspacing - wirewid/2., y + wirewidF))) # v = Vector(-2*padsize-5*wirespaceF/2.-wirewidF, -groundoffset) # Ground Left ## toReturn.add(rect(v, v + Vector(padsize, -padsize))) # toReturn.add(rect(v + Vector(padsize, 0), Vector((-numdisks/2.)*diskspacing - wirewid/2., -groundoffset - wirewidF))) toReturn.add(toReturn*Matrix(-1,0,0,1)) # FLIP HORIZ #toReturn.add(rect(v - Vector(wirewidF + wirespaceF, wirewidF + wirespaceF), v - Vector(wirespaceF, - padsize - wirewidF - wirespaceF))) #toReturn.add(rect(Vector(v.x - (wirewidF + wirespaceF), 0), v - Vector(wirespaceF, - padsize - wirewidF - wirespaceF))) toReturn.add(rect(Vector(v.x - (2*wirewidF + wirespaceF), 0), Vector(v.x-wirespaceF, 200))) toReturn.add(rect(Vector(7*wirewidF/2. + 3*wirespaceF + padsize, 0), Vector(11*wirewidF/2. + 3*wirespaceF + padsize, 200))) # Ground line toReturn.add(rect(v + Vector(-wirespaceF, padsize + wirespaceF), Vector(-v.x + wirespaceF, v.y + padsize + wirespaceF + wirewidF))) toReturn.add(rect(Vector(-wirewidF/2., y + disky + 3*wirespaceF + wirewidF), Vector(wirewidF/2., y + disky + 2*wirespaceF + wirewidF + padsize))) toReturn.add(rect(Vector(-wirewid/2., y + disky + wirewidF), Vector(wirewid/2., y + disky + 3*wirespaceF + wirewidF))) toReturn.add(tipobj) # if not (lrpad & 0x01): # Make left pad # v = Vector(-2*padsize-5*wirespaceF/2.-wirewidF, y) # Left # toReturn.add(rect(v, v + Vector(padsize, padsize))) # v = Vector(-2*padsize-5*wirespaceF/2.-wirewidF, -groundoffset) # Ground Left # toReturn.add(rect(v, v + Vector(padsize, -padsize))) # # if not (lrpad & 0x02): # Make right pad # v = Vector(-(-padsize-5*wirespaceF/2.-wirewidF), y) # Left # toReturn.add(rect(v, v + Vector(padsize, padsize))) # v = Vector(-(-padsize-5*wirespaceF/2.-wirewidF), -groundoffset) # Ground Left # toReturn.add(rect(v, v + Vector(padsize, -padsize))) # Ground gwid = diskspacing*numdisks/2. + electwid/2. gwid2 = diskspacing*numdisks/2. + wirewid/2. # toReturn.add(rect(Vector(-gwid, -gespace/2.), Vector(gwid, -groundoffset)).setMaterial(3)) # toReturn.add(rect(Vector(-gwid2, -gespace/2.-wirewidF), Vector(gwid2, -gespace/2.)).setMaterial(3)) toReturn.add(rect(Vector(-gwid2, wirespaceF/2.), Vector(gwid2 + wirespaceF, wirewidF + wirespaceF/2.)).setMaterial(3)) toReturn.add((rect(v - Vector(wirewidF + wirespaceF, wirewidF + wirespaceF), v - Vector(wirespaceF, - padsize - wirewidF - wirespaceF))*Matrix(-1,0,0,1)).setMaterial(3)) toReturn.setMaterial(3) toReturn.add(gapStuff) toReturn.add(toReturn*Matrix(1,0,0,-1)) # FLIP VERT toReturn.add(rect(Vector(gwid2 + wirespaceF, -wirewidF - wirespaceF/2.), Vector(gwid2 + wirespaceF + wirewidF, wirewidF + wirespaceF/2.)).setMaterial(3)) toReturn.add(rect(Vector(gwid2 + wirespaceF + wirewidF, - wirewidF), Vector(7*wirewidF/2. + 3*wirespaceF + padsize, wirewidF)).setMaterial(3)) # toReturn.add(rect(Vector(3*wirewidF/2. + 3*wirespaceF + padsize, -wirespaceF/2.), Vector(5*wirewidF/2. + 3*wirespaceF + 2*padsize, -wirespaceF/2. + padsize)).setMaterial(3)) # toReturn.add((rect(v - Vector(wirewidF + wirespaceF, wirewidF + wirespaceF), v - Vector(wirespaceF, - padsize - wirewidF - wirespaceF))*Matrix(-1,0,0,1)).setMaterial(3)) # toReturn.add((font.shapeFromStringBoundedCentered("42", -1, 7*5) + Vector(-85, 0)).setMaterial(3)) # return [toReturn.setMaterial(3), 2*padsize + 3*wirespaceF + groundoffset + gespace/2. + 3*wirewidF] return toReturn
def intersect_with_polygon(self, pts): current_pos = Vector(self.x + self.radius, self.y + self.radius) speed = Vector(self.speed_x, self.speed_y) new_pos = current_pos + speed min_dist = 1e9 result_speed = None result_position = None # Проверяем пересечения со сторонами pts.append(pts[0]) for i in range(len(pts) - 1): # Делаем сдвиг стороны наружу на радиус шара # Шар сжимаем до точки line = Vector(*pts[i]) - Vector(*pts[i + 1]) norm = line.rotate(90) / abs(line) # a и b - новые точки сдвинутой прямой a = Vector(*pts[i]) + norm * self.radius b = Vector(*pts[i + 1]) + norm * self.radius intersect, intersect_point = geometry.intersect_sector_sector( a, b, current_pos, new_pos ) if intersect and abs(intersect_point - current_pos) < min_dist: min_dist = abs(intersect_point - current_pos) if self.parent.debug: self.parent.debug_line( a.x, a.y, b.x, b.y ) self.parent.debug_point( intersect_point.x, intersect_point.y ) line = Vector(*pts[i]) - Vector(*pts[i + 1]) angle_cos = speed.scalar_mul(line) / \ (abs(speed) * abs(line)) angle = math.acos(angle_cos) angle = angle / math.pi * 180 result_speed = speed.rotate(2 * angle) result_position = intersect_point # Проверка пересечения с углами for x, y in pts: point = Vector(x, y) # Ищем точки пересечения вектора скорости мяча # с окружностью в точке прямоугольника и радиуса мяча intersect_points = geometry.intersect_line_circle( current_pos, speed, point, self.radius ) # Перебираем точки пересечения и выбираем нужную for intersect_point in intersect_points: if abs(intersect_point - current_pos) > abs(speed): continue if (intersect_point - current_pos).scalar_mul(speed) <= 0: continue if abs(intersect_point - current_pos) >= min_dist: continue min_dist = abs(intersect_point - current_pos) if self.parent.debug: self.parent.debug_point( intersect_point.x, intersect_point.y ) # Получаем направляющий вектор касательной # к окружности в найенной точке tangent = (point - intersect_point).rotate(90) # Найдем косинус угла между вектором скорости и # касательной angle_cos = speed.scalar_mul(tangent) /\ (abs(speed) * abs(tangent)) # Переведем угол в градусы angle = math.acos(angle_cos) angle = angle / math.pi * 180 result_speed = speed.rotate(2 * angle) result_position = intersect_point if result_speed and result_position: self.speed_x = result_speed.x self.speed_y = result_speed.y self.x = result_position.x - self.radius - self.speed_x * 0.9 self.y = result_position.y - self.radius - self.speed_y * 0.9 return True return False
def __init__(self, r, g=0, b=0): Vector.__init__(self, r, g, b)