def getFaceNormal(facepath): verts = getWindingOrder(facepath, False) if len(verts) < 3: return (1, 0, 0 ) #if there are less than 3 verts we have no uv area so bail #get edge vectors and cross them to get the uv face normal vertAPos = Vector( cmd.xform(verts[0], query=True, worldSpace=True, absolute=True, translation=True)) vertBPos = Vector( cmd.xform(verts[1], query=True, worldSpace=True, absolute=True, translation=True)) vertCPos = Vector( cmd.xform(verts[2], query=True, worldSpace=True, absolute=True, translation=True)) vecAB = vertBPos - vertAPos vecBC = vertCPos - vertBPos faceNormal = (vecAB ^ vecBC).normalize() return faceNormal
def find_ship_orientation(self): #head left, back, right #Returns the unit direction that the ship is oriented ship_facing_vector = Vector(self.point_list[0]) - Vector( self.point_list[2]) ship_facing_vector._normalize() return ship_facing_vector
def test_get_theta(): v = Vector(30, 0) assert math.isclose(v.theta, 0.0) v = Vector(30, 30) assert math.isclose(v.theta, math.pi / 4.0) v = Vector(-30, 0) assert math.isclose(v.theta, math.pi)
def drawScreenGrid(self, e1, e2, start, range1=[-25, 25], range2=[-25, 25], color="#d0d0d0", width=None): if not width: width = self.LINE_WIDTH / 3 start = Vector(start) e1 = Vector(e1) - start e2 = Vector(e2) - start for i in range(*range1): s = start + i * e2 self.drawScreenLine(s, s + e1, color=color, width=width if i != 0 else width * 3) for i in range(*range2): s = start + i * e1 self.drawScreenLine(s, s + e2, color=color, width=width if i != 0 else width * 3)
def test_scalar_mult(): x = Vector(1, 2) y1 = 2*x y2 = x*2 z = Vector(2, 4) nt.assert_equals(y1, z) nt.assert_equals(y2, z)
def loop_position(self, loop_offset): ''' This method calculates the center point of the ship by finding the midpoint between the head of the ship and the back indent of the ship Since the self.point_list is all tuples and not vectors (because the pygame.polygon method needs just tuples), we have to first convert them all to vectors ''' vector_list = [] for point_pair in self.point_list: vector_list.append(Vector(point_pair)) center_vector = vector_list[0] - vector_list[2] center_vector.x, center_vector.y = center_vector.x / 2, center_vector.y / 2 midpoint = vector_list[0] - center_vector #print(midpoint) loop = False if midpoint.x >= GAME_WIDTH + loop_offset: # Works self.location = Vector((loop_offset * -1, self.location.y)) loop = True elif midpoint.x <= loop_offset * -1: self.location = Vector((GAME_WIDTH, self.location.y)) loop = True elif midpoint.y <= loop_offset * -1: self.location = Vector((self.location.x, GAME_HEIGHT)) loop = True elif midpoint.y >= GAME_HEIGHT + loop_offset: # Works self.location = Vector((self.location.x, loop_offset * -1)) loop = True if loop: self.calculate_vertices()
def giterate(self, fn): ''' Iterate over the generated vectors This method is simple, but the generated vector order is really inefficient. A simplifier should improve the result :type fn: func(srcx, srcy, dstx, dsty) :param fn: function to call on each iteration ''' # # for each 2 adjacent vectors # for i in range(len(self._points)): s = self._points[i] d = self._points[(i + 1) % len(self._points)] self._l.debug('main vectors: %s' % Vector(s, d)) sxst = s.x / self._npoints # source x step syst = s.y / self._npoints # source y step dxst = d.x / self._npoints # dest x step dyst = d.y / self._npoints # dest y step # # generate each internal vector # for p in range(1, self._npoints): sp = p # current point in source dp = self._npoints - p # current points in dest sx = sxst * sp sy = syst * sp dx = dxst * dp dy = dyst * dp s = Point(sx, sy) d = Point(dx, dy) fn(Vector(s, d))
def handle_moving(self, dt): i, j = self.index if self.target_index is None: # if there is no target block, move randomly self.target_index = i + randrange(-1, 2), j + randrange(-1, 2) if not self.in_range(*self.target_index): # if it's not in range, move closer. spos = Vector(*self.index) dpos = Vector(*self.target_index) angle = spos.angle(dpos) index = next_cell(*self.index, angle) will_reach = False else: index = self.target_index will_reach = True if self.board.block_exists(*index, self.level): self.block = self.board.get_block(*index, self.level) self.mine() return cont = self.stumble(*index, dt) if not cont: self.move_time = 0. if will_reach: self.target_index = None self.stop() return
def handle_searching(self, dt): block = self.target_block if block is None or block.is_broken(): block = self.best_block() if block is None: # move randomly self.move() return self.block = block index = block.index p, q = index if not self.in_range(p, q): # move towards the block # target_index should be the position right before the block, # not the block's index. spos = Vector(p, q) dpos = Vector(*self.index) angle = spos.angle(dpos) index = next_cell(p, q, angle) self.target_index = index self.move() else: self.mine() return
def test_GQ_to_GP_expansion(): # noqa for mu in Partition.all(25, strict=True): print('mu =', mu) print() print(Partition.printable(mu, shifted=True)) print() n = len(mu) q = GQ(n, mu) expansion = SymmetricPolynomial.GP_expansion(q) normalized = Vector({ tuple(nu[i] - mu[i] for i in range(len(mu))): c * sgn(mu, nu) * BETA**(sum(nu) - sum(mu)) / 2**(len(mu) - sum(nu) + sum(mu)) for nu, c in expansion.items() }) unsigned = all(c > 0 for c in normalized.values()) print(' mu =', mu, 'n =', n) print(' expansion =', expansion) print(' normalized expansion =', normalized) assert all(len(nu) == 0 or max(nu) <= 1 for nu in normalized) assert all(len(nu) == len(mu) for nu in expansion) assert all(Partition.contains(nu, mu) for nu in expansion) assert all(c % 2**(len(mu) - sum(nu) + sum(mu)) == 0 for nu, c in expansion.items()) assert unsigned expected = { tuple(mu[i] + a[i] for i in range(len(a))) for a in zero_one_tuples(len(mu)) if all( mu[i - 1] + a[i - 1] > mu[i] + a[i] for i in range(1, len(a))) } print(' expected =', expected) assert set(expansion) == expected print() print()
def Bathroom_Window(input): a = json.loads(input) v_acc = Vector(a["x"], a["y"], a["z"]) v_earth = Vector(0, 0, -1) angle = v_acc.angle(v_earth) log.debug("Bathroom Window>input(%s) =>output(%f)" % (input, angle)) return angle
def initialize_particles(**kwargs): """ Initialize N particles in a circular distribution around a center point, where N=number. Keyword arguments include a radius from the center, an identifier pattern and other keyword arguments that would instantiate a particle. """ # Initialize variables needed to do initialization klass = kwargs.get('type', Particle) number = kwargs.get('number', world_parameters.get('team_size')) center = kwargs.get('center', (750,750)) radius = kwargs.get('radius', 100) team = kwargs.get('team', 'ally') maxvel = kwargs.get('maximum_velocity', world_parameters.get('maximum_velocity')) home = kwargs.get('home', None) params = kwargs.get('params', world_parameters) # Generate coordinates and particles coords = zip(*circular_distribute(num=number, center=center, r=radius)) for idx, coord in enumerate(coords): position = Vector.arrp(*coord) velocity = Vector.rand(maxvel) if maxvel > 0 else Vector.zero() name = team + "%02i" % (idx+1) yield klass(position, velocity, name, team=team, home=home, params=params)
def initialize_particles(**kwargs): """ Initialize N particles in a circular distribution around a center point, where N=number. Keyword arguments include a radius from the center, an identifier pattern and other keyword arguments that would instantiate a particle. """ # Initialize variables needed to do initialization klass = kwargs.get('type', Particle) number = kwargs.get('number', world_parameters.get('team_size')) center = kwargs.get('center', (750, 750)) radius = kwargs.get('radius', 100) team = kwargs.get('team', 'ally') maxvel = kwargs.get('maximum_velocity', world_parameters.get('maximum_velocity')) home = kwargs.get('home', None) params = kwargs.get('params', world_parameters) # Generate coordinates and particles coords = zip(*circular_distribute(num=number, center=center, r=radius)) for idx, coord in enumerate(coords): position = Vector.arrp(*coord) velocity = Vector.rand(maxvel) if maxvel > 0 else Vector.zero() name = team + "%02i" % (idx + 1) yield klass(position, velocity, name, team=team, home=home, params=params)
def distancePointSegment(a,Vbc,b,c): #returns min_distance between bc and a and the point of intersection of perpendicular from a on bc Vab=Vector.from_points(b, a) Vac=Vector.from_points(c, a) zero_vector=Point(0,0,0) min_distance=100 final_point=[] type=[] if Vbc.magnitude()<.000001: return [9999999,[a.x,a.y]] if abs(Vab.dot(Vbc)/Vbc.magnitude())<= Vbc.magnitude() and abs(Vac.dot(Vbc)/Vbc.magnitude())<= Vbc.magnitude(): min_distance=(Vab.cross(Vbc)).magnitude()/Vbc.magnitude() perpendicular_point_vector=Vbc.multiply(abs(Vab.dot(Vbc))/Vbc.magnitude()/Vbc.magnitude()) final_point=perpendicular_point_vector.sum(Vector.from_points(zero_vector,b)) type="middle" else : min_distance=min([Vab.magnitude(),Vac.magnitude()]) if min_distance==Vab.magnitude(): final_point=Vector.from_points(zero_vector, b) type="vertex" else: final_point=Vector.from_points(zero_vector, c) type="vertex" return [min_distance,[final_point.x,final_point.y]]
def test_modulo(): v = Vector(3, 4) assert v.mod == 5.0 v = Vector(30, 0) assert v.mod == 30.0 v = Vector(0, 30) assert v.mod == 30.0
def test_set_theta(): v = Vector(3, 4) v.theta = 0.0 assert math.isclose(v.x, 5.0) assert math.isclose(v.y, 0.0) v.theta = math.pi / 2.0 assert math.isclose(v.x, 0.0) assert math.isclose(v.y, 5.0)
def getFaceNormal(self, face): points = [] for v in face: points.append(Point(v[0], v[1], v[2])) vecA = Vector.from_points(points[0], points[1]) vecB = Vector.from_points(points[0], points[2]) vecResult = Vector.cross(vecA, vecB) return vecResult
def fn(x): vec = x if type(x) == Vector else Vector({x: 1}) for op in reversed(args): ans = Vector(printer=vec.printer) for mu in vec: ans += vec[mu] * op(mu) vec = ans return vec
def Bathroom_Heating(input): a = json.loads(input) v_acc = Vector(a["x"], a["y"], a["z"]) v_closed = Vector(0.213, -0.998, -0.166) #zero reference angle = safe_angle(v_acc, v_closed) if (type(angle) == float): #angle = v_acc.angle(v_closed) log.debug("Bathroom Heating>input(%s) =>output(%f)" % (input, angle)) return angle
def op(mu): for j in range(len(mu)): if mu[j] == i - 1: nu = mu[:j] + (i, ) + mu[j + 1:] return Vector({nu: 1}) if i == 1: nu = mu + (1, ) return Vector({nu: 1}) return Vector()
def ang(v1, v2): #返回v1至v2旋转的角度,æ£ä¸ºé¡ºæ—¶é’ˆï¼Œè´Ÿä¸ºé€†æ—¶é’ˆ v = Vector(0, 1, 0) x = v.angle(v1) y = v.angle(v2) a = v1.angle(v2) if min(y - x, y + 360 - x) > 0: return a else: return -a
def test_GQ_pieri_slow(): # noqa for mu in Partition.all(10, strict=True): for p in [1, 2, 3]: ans = Vector() for nu, tabs in Tableau.KLG_by_shape(p, mu).items(): ans += Vector( {nu: utils.beta**(sum(nu) - sum(mu) - p) * len(tabs)}) f = utils.GQ(len(mu) + 1, mu) * utils.GQ(len(mu) + 1, (p, )) assert ans == utils.GQ_expansion(f)
def P_expansion(cls, f): # noqa if f: t = max(f.lowest_degree_terms()) n = t.n c = f[t] mu = t.index() ans = cls.P_expansion(f - c * cls.schur_p(n, mu)) return ans + Vector({mu: c}) else: return Vector()
def __init__(self, x=WIDTH/2, y=HEIGHT/2): self.x = x self.y = y self.width = GRID - 2 self.vel = GRID self.dir = Vector(self.vel, 0, 0) self.body = [Vector(self.x, self.y, 0), Vector(self.x + GRID, self.y, 0), Vector(self.x + GRID * 2, self.y, 0)] self.dirs = {"left": False, "right": True, "up": False, "down": False}
def __init__(self): middle_x = GAME_WIDTH / 2 middle_y = GAME_HEIGHT / 2 self.location = Vector((middle_x, middle_y)) self.momentum_direction = Vector((0.0, 0.0)) self.ship_direction = Vector((0.0, -1.0)) # potentially useless self.acceleration = Vector((0.0, 0.0)) self.point_list = [] self.calculate_vertices() self.crashed = False
def GP_expansion(cls, f): # noqa if f: t = max(f.lowest_degree_terms()) n = t.n c = f[t] mu = t.index() ans = cls.GP_expansion(f - c * cls.stable_grothendieck_p(n, mu)) return ans + Vector({mu: c}) else: return Vector()
def __init__(self, *args, **kwargs): super(Asteroid, self).__init__(*args, **kwargs) OrientationMixin.__init__(self, *args, **kwargs) self.mass = kwargs.get('mass') self.current_vector = kwargs.get('vector', Vector(0, 0, 0)) # TODO(Austin) - Density of materials Determines size according to mass self.height = self.mass/250 * normalvariate(1, 0.2) self.width = self.mass/250 * normalvariate(1, 0.2) self.depth = self.mass/250 * normalvariate(1, 0.2) self.current_acceleration = Vector(0, 0, 0)
def schur_expansion(cls, f): if f: t = max(f) n = t.n c = f[t] mu = t.index() ans = cls.schur_expansion(f - c * cls.schur(n, mu)) return ans + Vector({mu: c}) else: return Vector()
def op(mu): shape = {(a + 1, a + b) for a in range(len(mu)) for b in range(1, mu[a] + 1)} cells = {(a, b) for (a, b) in shape if abs(a - b) == abs(i)} if len(cells) == 0: return Vector() a, b = max(cells) if (a + 1, b) in shape or (a, b + 1) in shape: return Vector() shape -= {(a, b)} return Vector({symmetric_undouble(shape): 1})
def clear(self): self.straight_pairs = [] self.interpolated_pairs = [] self.translate = Vector(0, 0, 0) self._axis = Vector(0, 0, 0) self._angle = 1 self.extrude = 2 self.color = False self.fixed = False self.joint = False self.showAxis = False self.id = ''
def test_eq(): mu = (3, 2, 1) nu = (2, 1) u = Vector.base(mu) v = Vector.base(nu) w = Vector() assert w == u - u == v - v assert u == u + w assert v == v - w assert 2 * v + 3 * u == u + v + u + v + u assert -1 * v + 2 * u == u - v + u
def getUVFaceNormal( facepath ): uvs = getWindingOrder(facepath) if len(uvs) < 3: return (1,0,0) #if there are less than 3 uvs we have no uv area so bail #get edge vectors and cross them to get the uv face normal uvAPos = cmd.polyEditUV(uvs[0], query=True, uValue=True, vValue=True) uvBPos = cmd.polyEditUV(uvs[1], query=True, uValue=True, vValue=True) uvCPos = cmd.polyEditUV(uvs[2], query=True, uValue=True, vValue=True) uvAB = Vector( [uvBPos[0]-uvAPos[0], uvBPos[1]-uvAPos[1], 0] ) uvBC = Vector( [uvCPos[0]-uvBPos[0], uvCPos[1]-uvBPos[1], 0] ) uvNormal = uvAB.cross( uvBC ).normalize() return uvNormal
def getAlignedBoundsForJoint(joint, threshold=0.65, onlyVisibleMeshes=True): """ looks at the verts the given joint/s and determines a local space (local to the first joint in the list if multiple are given) bounding box of the verts, and positions the hitbox accordingly if onlyVisibleMeshes is True, then only meshes that are visible in the viewport will contribute to the bounds """ theJoint = joint verts = [] # so this is just to deal with the input arg being a tuple, list or string. you can pass in a list # of joint names and the verts affected just get accumulated into a list, and the resulting bound # should be the inclusive bounding box for the given joints if isinstance(joint, (tuple, list)): theJoint = joint[0] for joint in joint: verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes) else: verts += jointVertsForMaya(joint, threshold, onlyVisibleMeshes) jointDag = api.getMDagPath(theJoint) jointMatrix = jointDag.inclusiveMatrix() vJointPos = OpenMaya.MTransformationMatrix(jointMatrix).rotatePivot( OpenMaya.MSpace.kWorld ) + OpenMaya.MTransformationMatrix(jointMatrix).getTranslation(OpenMaya.MSpace.kWorld) vJointPos = Vector([vJointPos.x, vJointPos.y, vJointPos.z]) vJointBasisX = OpenMaya.MVector(-1, 0, 0) * jointMatrix vJointBasisY = OpenMaya.MVector(0, -1, 0) * jointMatrix vJointBasisZ = OpenMaya.MVector(0, 0, -1) * jointMatrix bbox = OpenMaya.MBoundingBox() for vert in verts: # get the position relative to the joint in question vPos = Vector(xform(vert, query=True, ws=True, t=True)) vPos = vJointPos - vPos # now transform the joint relative position into the coordinate space of that joint # we do this so we can get the width, height and depth of the bounds of the verts # in the space oriented along the joint vPosInJointSpace = Vector((vPos.x, vPos.y, vPos.z)) vPosInJointSpace = vPosInJointSpace.change_space(vJointBasisX, vJointBasisY, vJointBasisZ) bbox.expand(OpenMaya.MPoint(*vPosInJointSpace)) minB, maxB = bbox.min(), bbox.max() return minB[0], minB[1], minB[2], maxB[0], maxB[1], maxB[2]
def getJointSizeAndCentre( joints, threshold=0.65, space=SPACE_OBJECT ): ''' minor modification to the getJointSize function in rigging.utils - uses the child of the joint[ 0 ] (if any exist) to determine the size of the joint in the axis aiming toward ''' centre = Vector.Zero( 3 ) if not isinstance( joints, (list, tuple) ): joints = [ joints ] joints = [ str( j ) for j in joints if j is not None ] if not joints: return Vector( (1, 1, 1) ) size, centre = rigUtils.getJointSizeAndCentre( joints, threshold, space ) if size.within( Vector.Zero( 3 ), 1e-2 ): while threshold > 1e-2: threshold *= 0.9 size, centre = rigUtils.getJointSizeAndCentre( joints, threshold ) if size.within( Vector.Zero( 3 ), 1e-2 ): size = Vector( (1, 1, 1) ) children = listRelatives( joints[ 0 ], pa=True, type='transform' ) if children: childPos = Vector( [ 0.0, 0.0, 0.0 ] ) childPosMag = childPos.get_magnitude() for child in children: curChildPos = Vector( xform( child, q=True, ws=True, rp=True ) ) - Vector( xform( joints[ 0 ], q=True, ws=True, rp=True ) ) curChildPosMag = curChildPos.get_magnitude() if curChildPosMag > childPosMag: childPos = curChildPos childPosMag = curChildPosMag axis = rigUtils.getObjectAxisInDirection( joints[ 0 ], childPos, DEFAULT_AXIS ) axisValue = getAttr( '%s.t%s' % (children[ 0 ], axis.asCleanName()) ) if space == SPACE_WORLD: axis = Axis.FromVector( childPos ) size[ axis % 3 ] = abs( axisValue ) centre[ axis % 3 ] = axisValue / 2.0 return size, centre
def __init__(self, normal_vector=None, constant_term=None): self.dimension = 2 if not normal_vector: all_zeros = ['0']*self.dimension normal_vector = Vector(all_zeros) self.normal_vector = Vector(normal_vector) if not constant_term: constant_term = Decimal('0') self.constant_term = Decimal(constant_term) self.set_basepoint()
def setup(self, axis=None): """ sets up the initial state of the pair node """ if axis: axis = abs(Axis(axis)) setAttr("%s.axis" % self.node, axis) # if we have two controls try to auto determine the orientAxis and the flipAxes if self.controlA and self.controlB: worldMatrixA = getWorldRotMatrix(self.controlA) worldMatrixB = getWorldRotMatrix(self.controlB) # so restPoseB = restPoseA * offsetMatrix # restPoseAInv * restPoseB = restPoseAInv * restPoseA * offsetMatrix # restPoseAInv * restPoseB = I * offsetMatrix # thus offsetMatrix = restPoseAInv * restPoseB offsetMatrix = worldMatrixA.inverse() * worldMatrixB AXES = AX_X.asVector(), AX_Y.asVector(), AX_Z.asVector() flippedAxes = [] for n in range(3): axisNVector = Vector(offsetMatrix[n][:3]) # if the axes are close to being opposite, then consider it a flipped axis... if axisNVector.dot(AXES[n]) < -0.8: flippedAxes.append(n) for n, flipAxes in enumerate(self.FLIP_AXES): if tuple(flippedAxes) == flipAxes: setAttr("%s.flipAxes" % self.node, n) break # this is a bit of a hack - and not always true, but generally singular controls built by skeleton builder will work with this value elif self.controlA: setAttr("%s.flipAxes" % self.node, 1) self.setWorldSpace(False)
def init(self): """Values that are used for managing the entity in update(), also they are reset for reusing the object instance""" self.health = 100 #Health of entity self.max_health = 100 #Maximum health level self.nodamage = False #Makes the entity indestructible (sets the health to maximum every update and ignores health < 0) self.team = None #Team of the entity belongs self.delete = False #Deletion flag, when its True, means that it can be reused, also with this true, update and draw is not called #Private or immutable values, self.__pos = Vector(0, 0) #The actual position of the unit self.__prev_pos = Vector(0, 0) #The previous position before a net update, used for interpolation self.__heading = 0 #Heading of the unit self.__prev_heading = 0 #Previous heading of unit, used for interpolation #Values that are not send during serialization self.__image = None #Contains Surface of actual frame self.__net_contact = time() #The last network update, used for interpolation
def initialize_resources(**kwargs): """ Initialize N particles in a linear distribution along a line with a slope and an intercept. N=number. Keyword arguments include the slope, the intercept, and the length of the line to distribute along. """ # Initialize variables needed to do initialization klass = kwargs.get('type', ResourceParticle) number = kwargs.get('number', world_parameters.get('deposits')) + 2 # Add two to skip corners length = kwargs.get('length', 3000) slope = kwargs.get('slope', -1) yint = kwargs.get('yint', 3000) coords = zip(*linear_distribute(number, length, slope, yint)) for idx, coord in enumerate(coords): if coord[0] in (0.0, length): continue # Skip corners yield klass(Vector.arrp(*coord), identifier="mineral%2i" % (idx+1))
def create_ally_home(): """ Constructs the ALLY_HOME on a per-simulation basis. """ return ResourceParticle(Vector.arrp(750,750), identifier="ally_home", stash_size=0)
class Line(object): NO_NONZERO_ELTS_FOUND_MSG = 'No nonzero elements found' def __init__(self, normal_vector=None, constant_term=None): self.dimension = 2 if not normal_vector: all_zeros = ['0']*self.dimension normal_vector = Vector(all_zeros) self.normal_vector = Vector(normal_vector) if not constant_term: constant_term = Decimal('0') self.constant_term = Decimal(constant_term) self.set_basepoint() def set_basepoint(self): try: n = self.normal_vector.coordinates c = self.constant_term basepoint_coords = ['0']*self.dimension initial_index = Line.first_nonzero_index(n) initial_coefficient = n[initial_index] basepoint_coords[initial_index] = c/initial_coefficient self.basepoint = Vector(basepoint_coords) except Exception as e: if str(e) == Line.NO_NONZERO_ELTS_FOUND_MSG: self.basepoint = None else: raise e def is_parallel(self, vector2): return self.normal_vector.is_parallel_to(vector2.normal_vector) def __eq__(self, vector2): if self.normal_vector.is_zero(): if not vector2.normal_vector.is_zero(): return False else: diff = self.constant_term - vector2.constant_term return MyDecimal(diff).is_near_zero() elif vector2.normal_vector.is_zero(): return False # consists of the same set of points if not self.is_parallel(vector2): return False direction_vector = self.basepoint - vector2.basepoint return direction_vector.is_orthogonal(self.normal_vector) def intersects(self, vector2): if(self == vector2): return 'The lines are equal, so there are infinite intersections.' if(self.is_parallel(vector2) and not self == vector2): return 'No intersection! The lines are parallel to each other.' A, B = self.normal_vector.coordinates C, D = vector2.normal_vector.coordinates k1 = self.constant_term k2 = vector2.constant_term x = ((D * k1) - (B * k2)) / ((A * D) - (B * C)) y = ((-C * k1) + (A * k2)) / ((A * D) - (B * C)) return Vector([x,y]) def __str__(self): num_decimal_places = 3 def write_coefficient(coefficient, is_initial_term=False): coefficient = round(coefficient, num_decimal_places) if coefficient % 1 == 0: coefficient = int(coefficient) output = '' if coefficient < 0: output += '-' if coefficient > 0 and not is_initial_term: output += '+' if not is_initial_term: output += ' ' if abs(coefficient) != 1: output += '{}'.format(abs(coefficient)) return output n = self.normal_vector.coordinates try: initial_index = Line.first_nonzero_index(n) terms = [write_coefficient(n[i], is_initial_term=(i==initial_index)) + 'x_{}'.format(i+1) for i in range(self.dimension) if round(n[i], num_decimal_places) != 0] output = ' '.join(terms) except Exception as e: if str(e) == self.NO_NONZERO_ELTS_FOUND_MSG: output = '0' else: raise e constant = round(self.constant_term, num_decimal_places) if constant % 1 == 0: constant = int(constant) output += ' = {}'.format(constant) return output @staticmethod def first_nonzero_index(iterable): for k, item in enumerate(iterable): if not MyDecimal(item).is_near_zero(): return k raise Exception(Line.NO_NONZERO_ELTS_FOUND_MSG)
class Entity(object): # pylint: disable=R0902 """The entity class which all entities in the world are subclassed, the only authorized to say "I'm your father" quote to everybody""" def __init__(self, uid, world): self.__uid = uid self.__world = world self.__load() self.init() def __load(self): """Loads data when entity is created, doesn't run when entity is reused, ideal for image loading for example""" pass def init(self): """Values that are used for managing the entity in update(), also they are reset for reusing the object instance""" self.health = 100 #Health of entity self.max_health = 100 #Maximum health level self.nodamage = False #Makes the entity indestructible (sets the health to maximum every update and ignores health < 0) self.team = None #Team of the entity belongs self.delete = False #Deletion flag, when its True, means that it can be reused, also with this true, update and draw is not called #Private or immutable values, self.__pos = Vector(0, 0) #The actual position of the unit self.__prev_pos = Vector(0, 0) #The previous position before a net update, used for interpolation self.__heading = 0 #Heading of the unit self.__prev_heading = 0 #Previous heading of unit, used for interpolation #Values that are not send during serialization self.__image = None #Contains Surface of actual frame self.__net_contact = time() #The last network update, used for interpolation def get_uid(self): """Returns the entity's unique id""" return self.__uid @property def pos(self): """Get the position""" return self.__pos @pos.setter def pos(self, pos, update_prev = True): """Set the position""" if update_prev: self.__prev_pos = pos self.__pos = Vector(pos) @property def heading(self): """Get the heading""" return self.__heading @heading.setter def heading(self, heading, update_prev = True): """Set the heading""" if update_prev: self.__prev_heading = heading self.__heading = heading def update(self): """Called when the entity is updated""" self.health_update() def health_update(self): """Checks health""" if self.nodamage: self.health = self.max_health elif (self.health <= 0): self.delete = True def draw(self): """Called when the entity needs to be drawed""" graphics = self.__world.graphics graphics.draw_circle(COLOR_WHITE, self.__pos.round(), 5) def serialize(self): """Called when needs to serialize this entity""" #Add the positions and heading x, y = self.pos.round() data = encode_word(x) data = data + encode_word(y) data = data + encode_word(self.heading) return data def deserialize(self, data): """Called when needs to deserialize information on this entity""" #Get the x y coordinates and heading in first 3 words bytes index = 0 self.x = decode_word(data[index:index+2]) index = index + 2 self.y = decode_word(data[index:index+2]) index = index + 2 self.heading = decode_word(data[index:index+2]) def net_update(self): """Update the network contact time""" self.__net_contact = time()
def generate_border(self, fn): ''' border of the entire device since the border is diagonal, it takes some computation ... also, in order to improve the cutting time, we need to modify the diagonals, so they are not emitted (fn) here. ''' sample_vector = Vector(Point(self.bend_length_max, 0), Point(self.bend_length_max - self.bend_length_step, self.distance_between_bends)) left_m = sample_vector.m height = (self.bend_count - 1) * self.distance_between_bends + self.margin_top + self.margin_bottom left_b = height left_vector = Vector(Point(0, height), Point((0 - left_b) / left_m, 0)) # find the ending point of the right side of the first bend first_bend_y = self.get_bend_y(0) first_bend_start_x = left_vector.x_for_y(first_bend_y) first_bend_ending_x = first_bend_start_x + (self.margin_sides + self.bend_length_min) * 2 + self.resistor_length # find the ending point of the right side of the second bend next_bend_y = self.get_bend_y(1) next_bend_start_x = left_vector.x_for_y(next_bend_y) next_bend_ending_x = next_bend_start_x + (self.margin_sides + self.bend_length_min + self.bend_length_step) * 2 + self.resistor_length # now create the vector to calculate the formula refv = Vector(Point(first_bend_ending_x, first_bend_y), (Point(next_bend_ending_x, next_bend_y))) right_vector = Vector(refv.point_for_y(height), refv.point_for_y(0)) # upper border v = Vector(left_vector.point_for_y(0), right_vector.point_for_y(0)) fn(v) v = Vector(left_vector.point_for_y(height), right_vector.point_for_y(height)) fn(v) self.dim = Point(right_vector.x_for_y(height), height) self.left_vector = left_vector self.right_vector = right_vector
def create_enemy_home(): """ Constructs the ENEMY_HOME on a per-simulation basis. """ return ResourceParticle(Vector.arrp(2250,2250), identifier="enemy_home", stash_size=0)
def pos(self, pos, update_prev = True): """Set the position""" if update_prev: self.__prev_pos = pos self.__pos = Vector(pos)
class Plane(object): NO_NONZERO_ELTS_FOUND_MSG = 'No nonzero elements found' def __init__(self, normal_vector=None, constant_term=None): self.dimension = 3 if not normal_vector: all_zeros = ['0']*self.dimension normal_vector = Vector(all_zeros) self.normal_vector = Vector(normal_vector) if not constant_term: constant_term = Decimal('0') self.constant_term = Decimal(constant_term) self.set_basepoint() def set_basepoint(self): try: n = self.normal_vector.coordinates c = self.constant_term basepoint_coords = ['0']*self.dimension initial_index = Plane.first_nonzero_index(n) initial_coefficient = n[initial_index] basepoint_coords[initial_index] = c/initial_coefficient self.basepoint = Vector(basepoint_coords) except Exception as e: if str(e) == Plane.NO_NONZERO_ELTS_FOUND_MSG: self.basepoint = None else: raise e def is_parallel(self, plane): return self.normal_vector.is_parallel_to(plane.normal_vector) def __eq__(self, plane): if self.normal_vector.is_zero(): if not plane.normal_vector.is_zero(): return False else: diff = self.constant_term - plane.constant_term return MyDecimal(diff).is_near_zero() elif plane.normal_vector.is_zero(): return False if not self.is_parallel(plane): return False direction_vector = self.basepoint - plane.basepoint return direction_vector.is_orthogonal(self.normal_vector) def __str__(self): num_decimal_places = 3 def write_coefficient(coefficient, is_initial_term=False): coefficient = round(coefficient, num_decimal_places) if coefficient % 1 == 0: coefficient = int(coefficient) output = '' if coefficient < 0: output += '-' if coefficient > 0 and not is_initial_term: output += '+' if not is_initial_term: output += ' ' if abs(coefficient) != 1: output += '{}'.format(abs(coefficient)) return output n = self.normal_vector.coordinates try: initial_index = Plane.first_nonzero_index(n) terms = [write_coefficient(n[i], is_initial_term=(i==initial_index)) + 'x_{}'.format(i+1) for i in range(self.dimension) if round(n[i], num_decimal_places) != 0] output = ' '.join(terms) except Exception as e: if str(e) == self.NO_NONZERO_ELTS_FOUND_MSG: output = '0' else: raise e constant = round(self.constant_term, num_decimal_places) if constant % 1 == 0: constant = int(constant) output += ' = {}'.format(constant) return output @staticmethod def first_nonzero_index(iterable): for k, item in enumerate(iterable): if not MyDecimal(item).is_near_zero(): return k raise Exception(Plane.NO_NONZERO_ELTS_FOUND_MSG)