def haveClearShotOfTarget(self, target): owner = self.owner fleet = owner.fleet turretPosition = self.getPosition() targetPosition = target.getPosition() turretToTarget = calculate.subtractPoints(targetPosition, turretPosition) distanceSquaredToTarget = vector.getMagnitudeSquared(turretToTarget) headingToTarget = vector.normalize(turretToTarget) for friendlyShip in fleet.getAllShips(): friendPosition = friendlyShip.getPosition() turretToFriend = calculate.subtractPoints(friendPosition, turretPosition) distanceSquaredToFriend = vector.getMagnitudeSquared(turretToFriend) if distanceSquaredToFriend > distanceSquaredToTarget: continue headingToFriend = vector.normalize(turretToFriend) dotProductOfFriendAndTarget = calculate.dotProduct(headingToTarget, headingToFriend) if calculate.withinTolerance(dotProductOfFriendAndTarget, 1, self.clearShotTolerance): return False return True
def separate(agent, neighbors): agentPosition = agent.getPosition() cumulativeForce = (0, 0) for neighbor in neighbors: if neighbor == agent: continue neighborPosition = neighbor.getPosition() neighborToAgent = calculate.subtractPoints(agentPosition, neighborPosition) distanceToAgent = vector.getMagnitude(neighborToAgent) if distanceToAgent == 0: neighborHeadingToAgent = vector.normalize((random.random() - 1, random.random() - 1)) magnitude = 100 else: neighborHeadingToAgent = vector.normalize(neighborToAgent) magnitude = max(agent.length, agent.width) / distanceToAgent separationForceForThisNeighbor =\ calculate.multiplyVectorAndScalar(neighborHeadingToAgent, magnitude) cumulativeForce = calculate.addVectors(cumulativeForce, separationForceForThisNeighbor) return cumulativeForce
def updatePosition(self): owner = self.owner ownerPosition = owner.getPosition() position = convert.pointToWorldSpace(self.offset, ownerPosition, owner.getDirection()) ownerToGun = calculate.subtractPoints(position, ownerPosition) self.heading = vector.normalize(ownerToGun) self.position = position
def lineWithCircle(line, circle): circle_point, circle_radius = circle line_point1, line_point2 = line a = calculate.subtractPoints(circle_point, line_point1) b = calculate.subtractPoints(line_point2, line_point1) left_perpendicular = vector.getLeftPerpendicular(b) # Project a onto the left perpendicular vector a_onto_left_perpendicular = calculate.dotProduct( a, vector.normalize(left_perpendicular)) return math.pow(a_onto_left_perpendicular, 2) < math.pow(circle_radius, 2)
def align(agent, neighbors): #Save us from divide-by-zero if not neighbors: return (0, 0) cumulativeHeading = (0, 0) for neighbor in neighbors: neighborVelocity = neighbor.getVelocity() neighborHeading = vector.normalize(neighborVelocity) cumulativeHeading = calculate.addVectors(cumulativeHeading, neighborHeading) averageHeading = calculate.multiplyVectorAndScalar(cumulativeHeading, float(1) / len(neighbors)) return averageHeading
def targetIsInRange(self, target): gunPosition = self.getPosition() targetPosition = target.getPosition() gunToTarget = calculate.subtractPoints(targetPosition, gunPosition) distanceSquaredToTarget = vector.getMagnitudeSquared(gunToTarget) headingToTarget = vector.normalize(gunToTarget) headingDotProduct = calculate.dotProduct(self.heading, headingToTarget) if (distanceSquaredToTarget < self.firingRangeSquared and headingDotProduct > 0): return True return False
def avoidwalls(agent, walls): if not walls: return (0, 0) agentPosition = agent.getPosition() feelers = createFeelers(agent) closestWall = None closestIntersection = None distanceSquaredToClosestIntersection = None closestFeeler = None for feeler in feelers: for wall in walls: intersectPoint = intersect.lineWithLine(feeler, wall) if intersectPoint is None: continue agentToIntersection = calculate.subtractPoints(intersectPoint, agentPosition) distanceSquaredToIntersection = vector.getMagnitudeSquared(agentToIntersection) if closestIntersection is None or distanceSquaredToIntersection < distanceSquaredToClosestIntersection: distanceSquaredToClosestIntersection = distanceSquaredToIntersection closestWall = wall closestIntersection = intersectPoint closestFeeler = feeler if closestWall is None: return (0, 0) (closestFeelerOrigin, closestFeelerEndpoint) = closestFeeler (wallOrigin, wallEndpoint) = closestWall wallVector = calculate.subtractPoints(wallEndpoint, wallOrigin) intersectionToFeelerEndpoint = calculate.subtractPoints(closestFeelerEndpoint, closestIntersection) overshootLength = vector.getMagnitude(intersectionToFeelerEndpoint) normalizedWallVector = vector.normalize(wallVector) wallNormal = vector.getRightPerpendicular(normalizedWallVector) steeringForce = calculate.multiplyVectorAndScalar(wallNormal, overshootLength) return steeringForce
def lineSegmentWithCircle(line_segment, circle): if not lineWithCircle(line_segment, circle): return False circle_point, circle_radius = circle line_seg_point1, line_seg_point2 = line_segment # Line to circle vector (pick an endpoint) a = calculate.subtractPoints(circle_point, line_seg_point1) # Line segment vector b = calculate.subtractPoints(line_seg_point2, line_seg_point1) # a is the vector from line_point1 and the circle's center-point # b is the vector from line_point1 to line_point2 # If a and b are pointing in opposing directions, then there is # no intersection if calculate.dotProduct(a, b) <= 0: return False # Project a onto b. If this projection is longer than the # length of the line segment, then there is no intersection a_onto_b = calculate.dotProduct(a, vector.normalize(b)) return math.pow(a_onto_b, 2) <= vector.getMagnitudeSquared(b)
def test_normalizeFive(self): startVector = (0, 5) newVector = vector.normalize(startVector) self.assertEquals((0, 1), newVector)
def test_normalizeZero(self): startVector = (0, 0) newVector = vector.normalize(startVector) self.assertEquals((1, 0), newVector) '''
def test_normalizeOneHalf(self): startVector = (0, .5) newVector = vector.normalize(startVector) self.assertEquals((0, 1), newVector)
def normalizedDotProduct(vector1, vector2): vector1 = vector.normalize(vector1) vector2 = vector.normalize(vector2) return dotProduct(vector1, vector2)
def getHeading(self): return vector.normalize(self.velocity)