def update(self, walls, acceleration, friction): # Move by a given acceleration self.move(Vector(acceleration[0], acceleration[1])) # Iterate through all walls # and check for collisions for wall in walls: # Don't check walls if # they're too far from # a particle wallToLine = vector.subtract(wall.start, self.position) if (vector.magnitude(wallToLine) > vector.magnitude(wall.line)): continue # If the returned value is # greater than 0, the ball # is colliding with the wall clipVal = self.intersectsWall(wall) if (clipVal > 0): # Move the particle out of the wall dPos = vector.multiply(wall.normal, clipVal) self.position.addVector(dPos) # Bounce the particle off of the wall self.velocity = self.getReflection(copy.copy(wall.normal)) # Reduce the particle's velocity by # the friction coefficient self.velocity.scalarMultiply(friction)
def update(self, delta, all_boids, attractors, obstacles): """This is main function which figures out all the conditions and determine resultant change in the boid location per cycle. It calls all the function given above and find resultant change in location and applies it to the boid.""" #start with determining nearby boids. self.determine_nearby_boids(all_boids) # obstacles = self.nearby_obj(objs, _MIN_OBSTACLE_DISTANCE) self.nearby_obj(obstacles, _MIN_OBSTACLE_DISTANCE) #initializing all the change vectors # cohesion_factor = self.average_position() # alignment_factor = self.average_velocity() # seperation_factor = self.avoid_collisions(self.neighbours, _BOID_COLLISION_DISTANCE) p = self.all_in_one() cohesion_factor = p[0] alignment_factor = p[1] seperation_factor = p[2] collision_factor = self.avoid_collisions(self.obj_nearby, _MIN_OBSTACLE_DISTANCE) attraction_factor = self.attraction(attractors) bound_factor = self.know_bound() self.force_factors = [[_FACTOR_COHESION, cohesion_factor], [_FACTOR_ALIGNMENT, alignment_factor], [_FACTOR_BOID_AVOIDANCE, seperation_factor], [_FACTOR_OBSTACLE_AVOID, collision_factor], [_FACTOR_ATTRACT, attraction_factor], [_FACTOR_BOUND, bound_factor]] # print(_FACTOR_COHESION) # print(cohesion_factor) # y = _FACTOR_COHESION*cohesion_factor[0] for x in self.force_factors: self.velocity[0] += x[1][0] * x[0] self.velocity[1] += x[0] * x[1][1] * 0.2 self.velocity[2] += x[0] * x[1][2] velocity2 = vector.limit_magnitude(self.velocity, _SPEED_MAX, _SPEED_MIN, True) #changing the boids position in accordance with velocity. for i in range(0, len(self.position)): self.position[i] += delta * velocity2[i] # if (self.position[i] > self.bound[i]) or (self.position[i]< -self.bound[i]): # self.position[i] = -self.position[i] # for i in range(3): # if (self.position[i] > self.bound[i]) or (self.position[i]< -self.bound[i]): # self.position = vector.limit_magnitude(self.position, self.bound[i], -self.bound[i], True) self.force = self.mass * vector.magnitude( self.velocity[0] - velocity2[0], self.velocity[1] - velocity2[1], self.velocity[2] - velocity2[2]) / (self.dt * 50) self.velocity = velocity2 cross = vector.cross(self.velocity, self.position) self.ang_mom = self.mass * vector.magnitude(cross[0], cross[1], cross[2]) / 1000 self.energy = self.mass * (vector.magnitude( self.velocity[0], self.velocity[1], self.velocity[2])**2) / 4000000
def update(self, step_time): def change_dir_vel(entities, direction, velocity): for entity in entities: entity.body.direction = direction entity.body.set_velocity(velocity) if (self.moving_left or self.moving_right): if self.moving_left: change_dir_vel(self.paddles, Vector2(-1, 0), PADDLE_VELOCITY) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, Vector2(-1, 0), PADDLE_VELOCITY) else: change_dir_vel(self.paddles, Vector2(1, 0), PADDLE_VELOCITY) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, Vector2(1, 0), PADDLE_VELOCITY) else: change_dir_vel(self.paddles, ZERO2, magnitude(ZERO2)) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, ZERO2, magnitude(ZERO2)) if self.push_balls and self.game_status == GameLayer.INITIALIZATION: for ball in self.balls: if ball.body.is_static: ball.body.is_static = False v = Vector2(BALL_VELOCITY_X, BALL_VELOCITY_Y) change_dir_vel(self.balls, normalize(v), magnitude(v)) self.push_balls = False self.game_status = GameLayer.GAME_LOOP # Remove bricks that have been destroyed free_brick_list = [] for brick in self.bricks: if brick.health_points == 0: self.unregister_entity(brick) free_brick_list.append(brick) self.bricks = [b for b in self.bricks if free_brick_list.count(b) == 0] for paddle in self.paddles: # Integrate paddle paddle.body.rect.position = sum( paddle.body.rect.position, mul(paddle.body.direction, paddle.body.velocity * step_time)) # Relocate paddle position to a valid position range paddle.body.rect.position.x = utils.clamp( paddle.body.rect.position.x, 0, WINDOW_WIDTH - PADDLE_WIDTH) paddle.body.rect.position.y = WINDOW_HEIGHT - PADDLE_HEIGHT - PADDLE_LINE_SPACING for ball in self.balls: if ball.body.is_static: pos_r = Vector2((PADDLE_WIDTH - BALL_WIDTH) * 0.5, -BALL_HEIGHT) ball.body.rect.position = sum( self.paddles[0].body.rect.position, pos_r)
def update(self, step_time): def change_dir_vel(entities, direction, velocity): for entity in entities: entity.body.direction = direction entity.body.set_velocity(velocity) if(self.moving_left or self.moving_right): if self.moving_left: change_dir_vel(self.paddles, Vector2(-1,0), PADDLE_VELOCITY) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, Vector2(-1,0), PADDLE_VELOCITY) else: change_dir_vel(self.paddles, Vector2(1,0), PADDLE_VELOCITY) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, Vector2(1,0), PADDLE_VELOCITY) else: change_dir_vel(self.paddles, ZERO2, magnitude(ZERO2)) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, ZERO2, magnitude(ZERO2)) if self.push_balls and self.game_status == GameLayer.INITIALIZATION: for ball in self.balls: if ball.body.is_static: ball.body.is_static = False v = Vector2(BALL_VELOCITY_X, BALL_VELOCITY_Y) change_dir_vel(self.balls, normalize(v), magnitude(v)) self.push_balls = False self.game_status = GameLayer.GAME_LOOP # Remove bricks that have been destroyed free_brick_list = [] for brick in self.bricks: if brick.health_points == 0: self.unregister_entity(brick) free_brick_list.append(brick) self.bricks = [ b for b in self.bricks if free_brick_list.count(b) == 0 ] for paddle in self.paddles: # Integrate paddle paddle.body.rect.position = sum(paddle.body.rect.position, mul(paddle.body.direction, paddle.body.velocity * step_time)) # Relocate paddle position to a valid position range paddle.body.rect.position.x = utils.clamp(paddle.body.rect.position.x, 0, WINDOW_WIDTH - PADDLE_WIDTH) paddle.body.rect.position.y = WINDOW_HEIGHT - PADDLE_HEIGHT - PADDLE_LINE_SPACING for ball in self.balls: if ball.body.is_static: pos_r = Vector2((PADDLE_WIDTH - BALL_WIDTH) * 0.5, - BALL_HEIGHT) ball.body.rect.position = sum(self.paddles[0].body.rect.position, pos_r)
def set_velocity(self, velocity): magnitude = V.magnitude(velocity) # Limit velocity to prevent the body from escaping its borders if magnitude > self.maximum_speed: velocity *= self.maximum_speed / magnitude velocity = V.address_data(velocity) self.velocity[:] = velocity
def avoid_collisions(self, objs, collision_distance): # determine nearby objs using distance only nearby_objs = (obj for obj in objs if ( obj != self and vector.magnitude( obj.position[0] - self.position[0], obj.position[1] - self.position[1]) - self.size <= collision_distance)) c = [0.0, 0.0] for obj in nearby_objs: diff = obj.position[0] - self.position[0], obj.position[ 1] - self.position[1] inv_sqr_magnitude = 1 / ((vector.magnitude(*diff) - self.size)**2) c[0] = c[0] - inv_sqr_magnitude * diff[0] c[1] = c[1] - inv_sqr_magnitude * diff[1] return vector.limit_magnitude(c, MAX_COLLISION_VELOCITY)
def circle_circle(bodies, resolve=True): restitution = max(bodies[0].body_restitution, bodies[1].body_restitution) position_0 = bodies[0].position position_1 = bodies[1].position total_radius = bodies[0].radius + bodies[1].radius # 两个物体的距离如果没有相交,则返回false direction = position_0 - position_1 distance = V.magnitude(direction) if distance <= 0.0 or distance >= (total_radius): return False # 两个物体的距离如果相交 # 计算单位方向向量 normal = V.normalize(direction) penetration = total_radius - distance if resolve: Collision._resolve_circle_circle_velocity(bodies, normal, restitution) Collision._resolve_circle_circle_interpenetration( bodies, normal, penetration) return True
def __init__(self, rect, velocity, object_type, tag_ent, is_static=True): self.rect = rect self.set_velocity(vector.magnitude(velocity)) self.direction = vector.normalize(velocity) self.object_type = object_type self.is_static = is_static self.tag_ent = tag_ent
def determine_nearby_boids(self, all_boids): for boid in all_boids: diff = (boid.position[0] - self.position[0], boid.position[1] - self.position[1]) if (boid != self and vector.magnitude(*diff) <= BOID_RANGE and vector.angle_between(self.velocity, diff) <= BOID_VIEW_ANGLE): yield boid
def nearby_obj(self, objs, _MIN_OBSTACLE_DISTANCE): """It takes a list of predators and a safe distance from it and update the list of nearby objects in it.""" self.obj_nearby = [ obj for obj in objs if (vector.magnitude(obj.position[0] - self.position[0], obj.position[1] - self.position[1], obj.position[2] - self.position[2]) <= _MIN_OBSTACLE_DISTANCE) ]
def determine_nearby_boids(self, all_boids): """This function takes a list of boids as input update neighbours list of boids. It also takes field of view into consideration.""" if (len(all_boids) > 0): (self.neighbours).clear() for boid in all_boids: diff = (boid.position[0] - self.position[0], boid.position[1] - self.position[1], boid.position[2] - self.position[2]) if (boid != self and vector.magnitude(*diff) <= _RANGE_OF_BOID and vector.angle_between(self.velocity, diff) <= _VIEW_ANGLE): (self.neighbours).append(boid)
def circle_line(body, line, screen=None): # 计算circle与直线最近的点 relative_position = body.position - line.p1 projected_vector = line.direction * relative_position.dot( line.direction) closest_point = line.p1 + projected_vector # 记录参数 cx, cy = closest_point lx1, ly1 = line.p1 lx2, ly2 = line.p2 # Make sure that closest point lies on the line if lx1 - lx2 > 0: cx = max(min(cx, lx1), lx2) else: cx = min(max(cx, lx1), lx2) if ly1 - ly2 > 0: cy = max(min(cy, ly1), ly2) else: cy = min(max(cy, ly1), ly2) closest_point[:] = cx, cy distance = V.magnitude(body.position - closest_point) collided = distance < body.radius if collided: # Resolve interpenetration orthogonal_vector = relative_position - projected_vector penetration = body.radius - V.magnitude(orthogonal_vector) disposition = V.normalize(orthogonal_vector) * penetration body.position += disposition # Resolve Velocity velocity = body.get_velocity() - line.normal * body.get_velocity( ).dot(line.normal) * (1 + body.wall_restitution) body.set_velocity(velocity) return collided
def avoid_collisions(self, objs, collision_distance): """This takes list of objects nearby it and determines how much boid should change direction to avoid collission with them.""" c = [0.0, 0.0, 0.0] for obj in objs: diff = obj.position[0] - self.position[0], obj.position[ 1] - self.position[1], obj.position[2] - self.position[2] inv_sqr_magnitude = 1 / ( (vector.magnitude(*diff) - self.size[0])**2) c[0] = c[0] - inv_sqr_magnitude * diff[0] c[1] = c[1] - inv_sqr_magnitude * diff[1] c[2] = c[2] - inv_sqr_magnitude * diff[2] return vector.limit_magnitude(c, _COLLISION_VELOCITY_MAX)
def all_in_one(self): if len(self.neighbours) > 0: c = [0.0, 0.0, 0.0] sum_x, sum_y, sum_z = 0.0, 0.0, 0.0 sum_x1, sum_y1, sum_z1 = 0.0, 0.0, 0.0 for boid in self.neighbours: sum_x += boid.position[0] sum_y += boid.position[1] sum_z += boid.position[2] sum_x1 += boid.velocity[0] sum_y1 += boid.velocity[1] sum_z1 += boid.velocity[2] diff = boid.position[0] - self.position[0], boid.position[ 1] - self.position[1], boid.position[2] - self.position[2] inv_sqr_magnitude = 1 / ( (vector.magnitude(*diff) - self.size[0])**4) c[0] = c[0] - inv_sqr_magnitude * diff[0] c[1] = c[1] - inv_sqr_magnitude * diff[1] c[2] = c[2] - inv_sqr_magnitude * diff[2] average_x, average_y, average_z = (sum_x / len(self.neighbours), sum_y / len(self.neighbours), sum_z / len(self.neighbours)) out = [[ average_x - self.position[0], average_y - self.position[1], average_z - self.position[2] ]] average_x, average_y, average_z = (sum_x1 / len(self.neighbours), sum_y1 / len(self.neighbours), sum_z1 / len(self.neighbours)) out.append([ average_x - self.position[0], average_y - self.position[1], average_z - self.position[2] ]) out.append(vector.limit_magnitude(c, _COLLISION_VELOCITY_MAX, True)) return out else: return [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]
def intersectsWall(self, wall1): # Get the directional vector # representing the wall wallDir = vector.normalize(wall1.line) # Get the length of the line # from the start of the wall # to the nearest point to the ball projectedMag = vector.dot(wallDir, vector.subtract(self.position, wall1.start)) # Scale the directional vector # by the projected magnitude wallDir.scalarMultiply(projectedMag) # Get the line between the # ball and the nearest point on the wall wallToBall = vector.subtract(vector.add(wallDir, wall1.start), self.position) # Return the amount the wall # is intersecting with the ball return self.size - vector.magnitude(wallToBall)
def buildObject(self, newComp): # Create a new sketch. sketches = newComp.sketches xyPlane = newComp.xYConstructionPlane sketch0 = sketches.add(xyPlane) circles = sketch0.sketchCurves.sketchCircles p0 = adsk.core.Point3D.create(0, 0, 0) # create beam profile if self._outer_d > 0: circles.addByCenterRadius(p0, self._outer_d / 2.0) # outer circle if self._inner_d > 0: circles.addByCenterRadius(p0, self._inner_d / 2.0) # inner circle if self.length != 0: distance = adsk.core.ValueInput.createByReal(self.length) prof = sketch0.profiles.item(0) # mm150 = adsk.core.ValueInput.createByString("150 mm") # mm0 = adsk.core.ValueInput.createByString("0 mm") extrudes = newComp.features.extrudeFeatures extrudeInput = extrudes.createInput( prof, adsk.fusion.FeatureOperations.NewBodyFeatureOperation) distanceDefinition = adsk.fusion.DistanceExtentDefinition.create( distance) extrudeInput.setOneSideExtent( distanceDefinition, adsk.fusion.ExtentDirections.PositiveExtentDirection) obj = extrudes.add(extrudeInput) if obj.bodies.count > 0: body = obj.bodies.item(0) body.name = "Konecne" obj.name = "myTube" obj.partNumber = "xyss75478" # Create a collection of entities for move bodies = adsk.core.ObjectCollection.create() bodies.add(obj.bodies.item(0)) # Create a transform to do move move_vector = adsk.core.Vector3D.create(self.start_position[0], self.start_position[1], self.start_position[2]) vec = vector.create(self.start_position, self.end_position) vec_length = vector.magnitude(vec) beam_vector = adsk.core.Vector3D.create(vec[0], vec[1], vec[2]) start_vector = adsk.core.Vector3D.create(0, 0, 1) beam_vector.normalize() # radial distance transform = adsk.core.Matrix3D.create() transform.setToRotateTo(start_vector, beam_vector) moveFeats = newComp.features.moveFeatures moveFeatureInput = moveFeats.createInput(bodies, transform) moveFeats.add(moveFeatureInput) if move_vector.length != 0: transform = adsk.core.Matrix3D.create() transform.translation = move_vector moveFeats = newComp.features.moveFeatures moveFeatureInput = moveFeats.createInput(bodies, transform) moveFeats.add(moveFeatureInput)
print(result_vec_sum) # умножение вектора на скаляр result_vec_dist = vector.scalar_multiply(scalar, grades) print(result_vec_dist) # покомпонентное среднее значение списка векторов result_vec_mean = vector.vector_mean(A) print(result_vec_mean) # скалярное произведение result_dot = vector.dot(height_weight_age, grades) print(result_dot) # сумма квадратов вектора result_sum_of_squares = vector.sum_of_squares(grades) print(result_sum_of_squares) # длина вектора result_magnitude = vector.magnitude(grades) print(result_magnitude) # квадрат растояния между двумя векторами result_squared_distance = vector.squared_distance(grades, height_weight_age) print(result_squared_distance) # растояние между двумя векторами result_distance = vector.distance(grades, height_weight_age) print(result_distance)
# assertions.py from vector import (add, subtract, vector_sum, scalar_multiply, vector_mean, dot, sum_of_squares, magnitude, distance) from matrices import shape, identity_matrix, get_column, get_row, make_matrix # Vector assert add([1, 2, 3], [4, 5, 6]) == [5, 7, 9] assert subtract([5, 7, 9], [4, 5, 6]) == [1, 2, 3] assert vector_sum([[1, 2], [3, 4], [5, 6], [7, 8]]) == [16, 20] assert scalar_multiply(2, [1, 2, 3]) == [2, 4, 6] assert vector_mean([[1, 2], [3, 4], [5, 6]]) == [3, 4] assert dot([1, 2, 3], [4, 5, 6]) == 32 # 1 * 4 + 2 * 5 + 3 * 6 assert sum_of_squares([1, 2, 3]) == 14 # 1 * 1 + 2 * 2 + 3 * 3 assert magnitude([3, 4]) == 5 # Matrices assert shape([[1, 2, 3], [4, 5, 6]]) == (2, 3) # 2 rows, 3 columns assert identity_matrix(5) == [[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]
def step(self, robot_action=None, human_action=None, debug=False, n_steps=4): dt = 0.25 # dt is randomly in interval [1, 2) time_iter = dt * n_steps # 记录上一步的游戏状态 past_bottom_pos = self.bottom_mallet.get_position() # 如果输入参数是None,就使用AI move if robot_action is None: if self.use_object['puck']: # robot_action = self.bottom_ai.move() robot_action = [0, 0] else: robot_action = [0, 0] if human_action is None: if self.use_object['top_mallet']: human_action = self.top_ai.move() # human_action = [0, 0] elif not self.use_object['puck']: human_action = [0, 0] else: human_action = [0, 0] self.bot_mallet_motion.set_motion(robot_action) self.top_mallet_motion.set_motion(self.top_ai.move()) # self.bottom_ai_motion.update_motion(robot_action) # 用数组来储存n_steps循环中 # puck_was_hit 和 border_was_hit 和 scored 的值 n_puck_was_hit = np.zeros(n_steps, dtype=np.float32) n_hit_the_border = np.zeros(n_steps, dtype=np.float32) n_score_flag = np.zeros(n_steps, dtype=np.float32) for k in range(n_steps): # Clear forces from last frame for body in self.bodies: body.clear_accumulated_v() self.motions.update_motions() # Move bodies for body in self.bodies: body.speed_position_update(dt) # Check collisions between all possible pairs of bodies if self.use_object['top_mallet']: Collision.circle_circle([self.puck, self.top_mallet]) Collision.circle_circle([self.top_mallet, self.bottom_mallet]) if self.use_object['puck']: n_puck_was_hit[k] = bool( Collision.circle_circle([self.puck, self.bottom_mallet])) else: n_puck_was_hit[k] = False in_the_target = Collision.circle_circle( [self.bottom_mallet, self.bottom_target], resolve=False) # Make sure all bodies are within their borders collided = [False, False, False] for i, body in enumerate(self.bodies): for border in body.borders: if Collision.circle_line(body, border): collided[i] = True n_hit_the_border[k] = collided[2] puck_is_at_the_bottom = self.puck.position[1] > self.dim.center[1] distance_decreased = False if puck_is_at_the_bottom: distance = V.magnitude(self.puck.position - self.bottom_mallet.position) distance_decreased = distance < self.distance self.distance = distance else: self.distance = P.max_distance _, n_score_flag[k] = self.score.update(self.puck) puck_position = self.puck.get_position() puck_velocity = V.address_data(self.puck.get_velocity()) bottom_mallet_position = self.bottom_mallet.get_position() bottom_mallet_velocity = V.address_data( self.bottom_mallet.get_velocity()) for i in range(len(past_bottom_pos)): if np.linalg.norm(past_bottom_pos[i] - self.bottom_mallet.get_position()[i]) < 1e-5: bottom_mallet_velocity[i] = 0 else: pass top_mallet_position = self.top_mallet.get_position() top_mallet_velocity = V.address_data(self.top_mallet.get_velocity()) puck_was_hit = np.any(n_puck_was_hit == 1) hit_the_border = np.any(n_hit_the_border == 1) scored = None score_flag = 0 if np.any(n_score_flag == 1): score_flag = 1 self.score.add_bottom() scored = 'bottom' elif np.any(n_score_flag == -1): score_flag = -1 self.score.add_top() scored = 'top' puck_position_mode = bool( self.dim.center[1] <= puck_position[1] <= self.dim.rink_bottom) game_info = GameInfo([], puck_position, puck_velocity, bottom_mallet_position, bottom_mallet_velocity, top_mallet_position, top_mallet_velocity, robot_action, human_action, scored, score_flag, puck_was_hit, puck_is_at_the_bottom, distance_decreased, hit_the_border, in_the_target, time_iter, puck_position_mode) return game_info