def calculate_start(sprite, mouse_location): mouse_x, mouse_y = mouse_location sprite_center = [sprite.rect.centerx, sprite.rect.centery] move_vector = [ mouse_x - sprite.rect.centerx, mouse_y - sprite.rect.centery ] # normalize the move vector unit_move_vector = [ move_vector[0] / vector.length(move_vector), move_vector[1] / vector.length(move_vector) ] # calculate distance between the center of the player and the potential bullet start point distance = vector.distance(sprite_center, [ sprite_center[0] + unit_move_vector[0], sprite_center[1] + unit_move_vector[1] ]) # One number above the radius of the circle circumscribing the player sprite radius = hitbox_radius = math.ceil( (sprite.image.get_width() / 2) * math.sqrt(2)) # ensure that the bullet starts outside of the player hitbox while distance < hitbox_radius: move_vector = vector.multiply_scalar(unit_move_vector, radius) distance = vector.distance(sprite_center, [ sprite_center[0] + move_vector[0], sprite_center[1] + move_vector[1] ]) radius += 1 # raise me to lower iterations but possibly increase start distance return sprite_center[0] + move_vector[0], sprite_center[ 1] + move_vector[1]
def avoid_collisions_obstacles(self, obstacles, collision_distance): # determine nearby objs using distance only c = [0.0, 0.0] position = self.position for obj in obstacles: # if obj.x[0] < position[0] < obj.x[1] and obj.y[0] < position[1] < obj.y[1]: # print('error') if obj.x[0] < position[0] < obj.x[1]: diff = (position[1] - obj.y[0], position[1] - obj.y[1]) diff_vector = (0, -diff[np.argmin(np.abs(diff))]) elif obj.y[0] < position[1] < obj.y[1]: diff = (position[0] - obj.x[0], position[0] - obj.x[1]) diff_vector = (-diff[np.argmin(np.abs(diff))], 0) else: diff_vectors = [] corners = [(obj.x[0], obj.y[0]), (obj.x[0], obj.y[1]), (obj.x[1], obj.y[0]), (obj.x[1], obj.y[1])] for corner in corners: diff_vectors.append(vector.diff(position, corner)) diff_vector = diff_vectors[np.argmin( [vector.length(*dif) for dif in diff_vectors])] if vector.length(*diff_vector) - self.size <= collision_distance: inv_sqr_magnitude = 1 / ( (vector.length(*diff_vector) - self.size)**2) c[0] = c[0] - inv_sqr_magnitude * diff_vector[0] c[1] = c[1] - inv_sqr_magnitude * diff_vector[1] return c #vector.limit_length(c, 1, 0.5)
def getClosest(self, sectorList): minDistance = vector.length(self.getMiddle() - sectorList[0].getMiddle()) closestSector = sectorList[0] for s in sectorList: if vector.length(self.getMiddle() - s.getMiddle()) < minDistance: minDistance = vector.length(self.getMiddle() - s.getMiddle()) closestSector = s return closestSector
def avoid_collisions(self, objs, collision_distance): # determine nearby objs using distance only c = [0.0, 0.0] for obj in objs: diff = vector.diff(self.position, obj.position) if vector.length( *diff) - self.size - obj.size <= collision_distance: inv_sqr_magnitude = 1 / ( (vector.length(*diff) - self.size - obj.size)**2) c[0] = c[0] - inv_sqr_magnitude * diff[0] c[1] = c[1] - inv_sqr_magnitude * diff[1] return c # vector.limit_length(c, 1, 0.2)
def move_stick(self, bag): """ Moves the stick. :param bag: The parameter bag. :return: """ if 'position' not in bag.stick: bag.next.stick.position = strategy.SimpleStrategy.HOME_POSITION return if 'dest_position' not in bag.stick: position = bag.stick.position else: # move stick towards destination # ignore dest_direction and dest_velocity dist_moved = strategy.SimpleStrategy.STICK_MAX_SPEED * bag.time_diff direction = vector.from_to(bag.stick.position, bag.stick.dest_position) if dist_moved > vector.length(direction): position = bag.stick.dest_position else: direction = vector.mul_by(vector.normalize(direction), dist_moved * strategy.SimpleStrategy.STICK_MAX_SPEED) position = vector.add(bag.stick.position, direction) # set new position bag.next.stick.position = position
def setCamera(self,bbox=None,angles=None): """Sets the camera looking under angles at bbox. This function sets the camera angles and adjusts the zooming. The camera distance remains unchanged. If a bbox is specified, the camera will be zoomed to make the whole bbox visible. If no bbox is specified, the current scene bbox will be used. If no current bbox has been set, it will be calculated as the bbox of the whole scene. """ self.makeCurrent() # go to a distance to have a good view with a 45 degree angle lens if bbox is None: bbox = self.bbox else: self.bbox = bbox center,size = vector.centerDiff(bbox[0],bbox[1]) # calculating the bounding circle: this is rather conservative dist = vector.length(size) if dist <= 0.0: dist = 1.0 self.camera.setCenter(*center) if angles: self.camera.setRotation(*angles) self.camera.setDist(dist) self.camera.setLens(45.,self.aspect) self.camera.setClip(0.01*dist,100.*dist)
def predict_puck_movement(self, bag): #ausgefuehrt """ Predicts the pucks movement. :param bag: The parameter bag. :return: """ # need at least 2 points if len(self.buffer) < 2: return # loop over points direction_sum = (0, 0) for i in xrange(0, len(self.buffer) - 1): # get tuples and time diff current_tuple = self.buffer[i] next_tuple = self.buffer[i+1] time_diff = next_tuple[2] - current_tuple[2] # get direction (length is velocity) and divide by time_diff direction = vector.mul_by(vector.from_to(current_tuple, next_tuple), 1.0 / time_diff) # sum up direction_sum = vector.add(direction_sum, direction) # averaging direction = vector.mul_by(direction_sum, 1.0 / self.buffer_size) # add puck direction (normalized) and velocity bag.puck.velocity = vector.length(direction) bag.puck.direction = vector.normalize(direction) bag.next.puck.olddirection = bag.puck.direction
def dyna(self,x,y): """Perform dynamic zoom/pan/rotation functions""" w,h = self.width(),self.height() if self.dynamic == "trirotate": # set all three rotations from mouse movement # tangential movement sets twist, # but only if initial vector is big enough x0 = self.state # initial vector d = vector.length(x0) if d > h/8: x1 = [x-w/2, h/2-y, 0] # new vector a0 = math.atan2(x0[0],x0[1]) a1 = math.atan2(x1[0],x1[1]) an = (a1-a0) / math.pi * 180 ds = utils.stuur(d,[-h/4,h/8,h/4],[-1,0,1],2) twist = - an*ds #print "an,d,ds = ",an,d,ds,twist self.camera.rotate(twist,0.,0.,1.) self.state = x1 # radial movement rotates around vector in lens plane x0 = [self.statex-w/2, h/2-self.statey, 0] # initial vector dx = [x-self.statex, self.statey-y,0] # movement b = vector.projection(dx,x0) #print "x0,dx,b=",x0,dx,b if abs(b) > 5: val = utils.stuur(b,[-2*h,0,2*h],[-180,0,+180],1) rot = [ abs(val),-dx[1],dx[0],0 ] #print "val,rot=",val,rot self.camera.rotate(*rot) self.statex,self.statey = (x,y) elif self.dynamic == "pan": dist = self.camera.getDist() * 0.5 # hor movement sets x value of center # vert movement sets y value of center #panx = utils.stuur(x,[0,self.statex,w],[-dist,0.,+dist],1.0) #pany = utils.stuur(y,[0,self.statey,h],[-dist,0.,+dist],1.0) #self.camera.setCenter (self.state[0] - panx, self.state[1] + pany, self.state[2]) dx,dy = (x-self.statex,y-self.statey) panx = utils.stuur(dx,[-w,0,w],[-dist,0.,+dist],1.0) pany = utils.stuur(dy,[-h,0,h],[-dist,0.,+dist],1.0) #print dx,dy,panx,pany self.camera.translate(panx,-pany,0) self.statex,self.statey = (x,y) elif self.dynamic == "zoom": # hor movement is lens zooming f = utils.stuur(x,[0,self.statex,w],[180,self.statef,0],1.2) self.camera.setLens(f) elif self.dynamic == "combizoom": # hor movement is lens zooming f = utils.stuur(x,[0,self.statex,w],[180,self.state[1],0],1.2) #print "Lens Zooming: %s" % f self.camera.setLens(f) # vert movement is dolly zooming d = utils.stuur(y,[0,self.statey,h],[0.2,1,5],1.2) self.camera.setDist(d*self.state[0]) self.update()
def nearby_boids(self, all_boids): neighbours = [] for boid in all_boids: distance_vector = vector.diff(self.position, boid.position) if (boid != self and vector.length(*distance_vector) <= _BOID_RANGE and vector.angle_between( self.velocity, distance_vector) <= _BOID_VIEW_ANGLE): neighbours.append(boid) return neighbours
def first_intersection(ray, objects): # build a list of all intersections and remove Nones ps = [e.intersect(ray) for e in objects] ps = [p for p in ps if p is not None] try: # select the point closest to ray.orig p = min(ps, key=lambda p: length(p - ray.orig)) return p except ValueError: return None
def update(self, dt, level, playerPos): if self.timer > 0: self.timer -= 1 * dt if self.timer < 0: self.timer = 0 relplayer = vector.add([playerPos[1], playerPos[0]], vector.negative(self.pos)) if self.line_of_sight(level, playerPos): #move directly at the player if they can be seen if vector.length(relplayer) > 0.2: reldir = vector.normalized(relplayer) self.pos = vector.add( self.pos, [reldir[0] * self.speed * dt, reldir[1] * self.speed * dt]) else: #update the target position if the player moves to far away #from the original target position if len(self.nodes) == 0 or vector.distance( self.pos, self.nodes[len(self.nodes) - 1]) > 2: self.find_path(level, playerPos) else: #get the direction to move in rel = vector.add(self.nodes[len(self.nodes) - 1], vector.negative(self.pos)) #set the position to the vector if moving one step will cause #the enemy to move over the node if vector.length(rel) < self.speed * dt: self.pos = self.nodes[len(self.nodes) - 1] #return subset of original that doesn't include the first entry self.nodes.remove(self.nodes[len(self.nodes) - 1]) else: #move towards the node rel = vector.normalized(rel) self.pos = vector.add( self.pos, [rel[0] * self.speed * dt, rel[1] * self.speed * dt])
def cast_ray(r): # walk the ray the distance to the nearest object start = r[0] for s in range(MAX_STEPS): if vector.length(vector.subtract(r[0], start)) > MAX_DISTANCE: break d, s = min_distance(r[0]) if d < TOLERANCE: return ray_colour(r, s) r[0] = vector.add(r[0], vector.scale(r[1], d)) return 0, 0, 0
def update(self,dt,level,playerPos): if self.timer > 0: self.timer -= 1 * dt if self.timer < 0: self.timer = 0 relplayer = vector.add([playerPos[1],playerPos[0]],vector.negative(self.pos)) if self.line_of_sight(level,playerPos): #move directly at the player if they can be seen if vector.length(relplayer) > 0.2: reldir = vector.normalized(relplayer) self.pos = vector.add(self.pos,[reldir[0] * self.speed * dt, reldir[1] * self.speed * dt]) else: #update the target position if the player moves to far away #from the original target position if len(self.nodes) == 0 or vector.distance(self.pos,self.nodes[len(self.nodes) - 1]) > 2: self.find_path(level,playerPos) else: #get the direction to move in rel = vector.add(self.nodes[len(self.nodes) - 1],vector.negative(self.pos)) #set the position to the vector if moving one step will cause #the enemy to move over the node if vector.length(rel) < self.speed * dt: self.pos = self.nodes[len(self.nodes) - 1] #return subset of original that doesn't include the first entry self.nodes.remove(self.nodes[len(self.nodes) - 1]) else: #move towards the node rel = vector.normalized(rel) self.pos = vector.add(self.pos,[rel[0] * self.speed * dt,rel[1] * self.speed * dt])
def _check_for_wild_shot(self, bag): """ Checks if the latest puck position is a wild shot. Requires bag.puck.predicted_position. :param bag: The parameter bag :return: """ #TODO ueberlegen ob nutzen oder loeschen predicted_position_pixel = vector.coord_to_image_space(bag.puck.predicted_position, bag.table_boundaries) diff = vector.length(vector.from_to(bag.puck.position_pixel, predicted_position_pixel)) # use time_diff and velocity to play with this value #accepted = self.ACCEPTABLE_PUCK_POSITION_DIFF * bag.time_diff * max((1000 * self.last_path[-1][2]) if len(self.last_path) > 0 else 1.0, 1.0) #return diff > accepted return False
def go_home(self, bag): """ Starts to move the stick to its home position. :param bag: The parameter bag. :return: """ # can only go home if we actually have a stick if 'position' in bag.stick: dist_home = vector.length(vector.from_to(bag.stick.position, self.HOME_POSITION)) bag.stick.dest_position = self.HOME_POSITION bag.stick.dest_direction = (0, 0) bag.stick.dest_velocity = 0 bag.stick.dest_time = time.time() + dist_home / self.STICK_MAX_SPEED
def calculate_start(sprite, mouse_location): mouse_x, mouse_y = mouse_location sprite_center = [sprite.rect.centerx, sprite.rect.centery] move_vector = [mouse_x - sprite.rect.centerx, mouse_y - sprite.rect.centery] # normalize the move vector unit_move_vector = [move_vector[0] / vector.length(move_vector), move_vector[1] / vector.length(move_vector)] # calculate distance between the center of the player and the potential bullet start point distance = vector.distance(sprite_center, [sprite_center[0] + unit_move_vector[0], sprite_center[1] + unit_move_vector[1]]) # One number above the radius of the circle circumscribing the player sprite radius = hitbox_radius = math.ceil((sprite.image.get_width()/2) * math.sqrt(2)) # ensure that the bullet starts outside of the player hitbox while distance < hitbox_radius: move_vector = vector.multiply_scalar(unit_move_vector, radius) distance = vector.distance(sprite_center, [sprite_center[0] + move_vector[0], sprite_center[1] + move_vector[1]]) radius += 1 # raise me to lower iterations but possibly increase start distance return sprite_center[0] + move_vector[0], sprite_center[1] + move_vector[1]
def dynarot(self,x,y,action): """Perform dynamic rotation operation. This function processes mouse button events controlling a dynamic rotation operation. The action is one of PRESS, MOVE or RELEASE. """ if action == PRESS: w,h = self.width(),self.height() self.state = [self.statex-w/2, self.statey-h/2, 0.] elif action == MOVE: w,h = self.width(),self.height() # set all three rotations from mouse movement # tangential movement sets twist, # but only if initial vector is big enough x0 = self.state # initial vector d = length(x0) if d > h/8: # GD.debug(d) x1 = [x-w/2, y-h/2, 0] # new vector a0 = atan2(x0[0],x0[1]) a1 = atan2(x1[0],x1[1]) an = (a1-a0) / pi * 180 ds = utils.stuur(d,[-h/4,h/8,h/4],[-1,0,1],2) twist = - an*ds self.camera.rotate(twist,0.,0.,1.) self.state = x1 # radial movement rotates around vector in lens plane x0 = [self.statex-w/2, self.statey-h/2, 0] # initial vector dx = [x-self.statex, y-self.statey,0] # movement b = projection(dx,x0) if abs(b) > 5: val = utils.stuur(b,[-2*h,0,2*h],[-180,0,+180],1) rot = [ abs(val),-dx[1],dx[0],0 ] self.camera.rotate(*rot) self.statex,self.statey = (x,y) self.update() elif action == RELEASE: self.update() self.camera.saveMatrix()
def setView(self,bbox=None,side='front'): """Sets the camera looking from one of the named views. On startup, the predefined views are 'front', 'back', 'left', 'right', 'top', 'bottom' and 'iso'. This function does not only set the camera angles, but also adjust the zooming. If a bbox is specified, the camera will be zoomed to view the whole bbox. If no bbox is specified, the current scene bbox will be used. If no current bbox has been set, it will be calculated as the bbox of the whole scene. """ self.makeCurrent() # select view angles: if undefined use (0,0,0) angles = self.views.get(side,(0,0,0)) # go to a distance to have a good view with a 45 degree angle lens if type(bbox) == type(None): bbox = self.bbox else: self.bbox = bbox center,size = vector.centerDiff(bbox[0],bbox[1]) #print "Setting view for bbox",bbox #print "center=",center #print "size=",size # calculating the bounding circle: this is rather conservative dist = vector.length(size) #print "dist = ",dist self.camera.setCenter(*center) self.camera.setRotation(*angles) self.camera.setDist(dist) self.camera.setLens(45.,self.aspect) if dist > 0.0: self.camera.setClip(0.01*dist,100*dist) else: self.camera.setClip(0.0,1.0)
def evaluate(self, goal, goal2): dir = vector.normalize(vector.from_to(self.position, goal)) stop = vector.mult( vector.sub(self.velocity, vector.along(self.velocity, dir)), vector.length(self.velocity) * 2) return vector.normalize(vector.sub(dir, stop))
def distance_to(sphere, point): # direction = sphere.p - point # distance = length(direction) - radius d = vector.subtract(point, sphere[0]) return vector.length(d) - sphere[1]
if __name__ == "__main__": try: list1 = random.sample(range(-10, 20), 4) list2 = random.sample(range(-10, 20), 4) text = '\n\t First: {}\n\tSecond: {}\n' print('Values:' + text.format(list1, list2)) vect1 = vector.create(*list1) vect2 = vector.create(*list2) print('Vectors:' + text.format(vect1, vect2)) print('is_vector:\n') print(' Values:' + text.format(vector.is_vector(list1), vector.is_vector(list2))) print(' Vectors:' + text.format(vector.is_vector(vect1), vector.is_vector(vect2))) print('Length:' + text.format(vector.length(vect1), vector.length(vect2))) a = random.randrange(-15, 30) b = round(random.uniform(-15, 30), 4) print('Multiplication:' + '\n\tFirst and {}: {}\n\tSecond and {}: {}\n'.format( a, vector.multiply(vect1, a), b, vector.multiply(vect2, b))) print('Scalar multiplication:', round(vector.scalar_product(vect1, vect2), 4)) print('\nAngle:', vector.angle_between(vect1, vect2)) except Exception as err: print('Error occured during execution:', err) print('Type:', type(err))