def hide(agent, attacker, obstacles): distanceFromObstacleBoundary = 30 closestDistance = None closestHidingPlace = None attackerPosition = attacker.getPosition() agentPosition = agent.getPosition() for obstacle in obstacles: obstaclePosition = obstacle.getPosition() hidingPlaceDistanceToObstacle = distanceFromObstacleBoundary + obstacle.getRadius() attackerToObstacle = calculate.subtractPoints(obstaclePosition, attackerPosition) attackerDistanceToObstacle = vector.getMagnitude(attackerToObstacle) attackerDistanceToHidingPlace = hidingPlaceDistanceToObstacle + attackerDistanceToObstacle attackerToHidingPlace = vector.setMagnitude(attackerToObstacle, attackerDistanceToHidingPlace) hidingPlace = calculate.addPointAndVector(attackerPosition, attackerToHidingPlace) agentToHidingPlace = calculate.subtractPoints(hidingPlace, agentPosition) distanceToHidingPlace = vector.getMagnitude(agentToHidingPlace) if closestDistance is None or distanceToHidingPlace < closestDistance: closestDistance = distanceToHidingPlace closestHidingPlace = hidingPlace if closestHidingPlace is None: return evade.evade(agent, attacker) return arrive.arrive(agent, closestHidingPlace)
def pointWithLineSegment(point_c, line_segment): if not pointWithLine(point_c, line_segment): return False point_a, point_b = line_segment ab = calculate.subtractPoints(point_b, point_a) ac = calculate.subtractPoints(point_c, point_a) cb = calculate.subtractPoints(point_b, point_c) return (vector.getMagnitude(ac) + vector.getMagnitude(cb) == vector.getMagnitude(ab))
def pursueoffset(agent, targetAgent, targetToOffset): agentPosition = agent.getPosition() agentMaxSpeed = agent.getMaxSpeed() targetPosition = targetAgent.getPosition() targetDirection = targetAgent.getDirection() targetSpeed = targetAgent.getSpeed() targetVelocity = targetAgent.getVelocity() worldTargetToOffset = convert.vectorToWorldSpace(targetToOffset, targetPosition, targetDirection) offsetPosition = calculate.addPointAndVector(targetPosition, worldTargetToOffset) agentToOffset = calculate.subtractPoints(offsetPosition, agentPosition) distanceToOffset = vector.getMagnitude(agentToOffset) if targetSpeed == 0: lookAheadTime = 0 else: lookAheadTime = distanceToOffset / (agentMaxSpeed + targetSpeed) targetToPredictedPosition = calculate.multiplyVectorAndScalar(targetVelocity, lookAheadTime) predictedOffsetPosition = calculate.addPointAndVector(offsetPosition, targetToPredictedPosition) return arrive.arrive(agent, predictedOffsetPosition, .9)
def prioritizedRunningSum(self): force = (0, 0) remaining_reservoir = self.force_reservoir for behaviorKeyword in self.keywords: action = self.actions[behaviorKeyword] if action is None: continue arguments = (self.agent,) + action behaviorFunction = self.steeringFunctions[behaviorKeyword] weight = self.weight[behaviorKeyword] forceForBehavior = calculate.multiplyVectorAndScalar(behaviorFunction(*arguments), weight) forceForBehavior = vector.truncate(forceForBehavior, remaining_reservoir) magnitudeForBehaviorForce = vector.getMagnitude(forceForBehavior) remaining_reservoir -= magnitudeForBehaviorForce force = calculate.addVectors(force, forceForBehavior) if remaining_reservoir <= 0: break force = vector.truncate(force, self.agent.getMaxForce()) return force
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 pursue(agent, target): agentHeading = agent.getHeading() targetHeading = target.getHeading() targetPosition = target.getPosition() relativeHeading = calculate.dotProduct(agentHeading, targetHeading) #If the target is heading at me, then just Seek if relativeHeading < -.95: return seek.seek(agent, targetPosition) agentPosition = agent.getPosition() agentMaxSpeed = agent.getMaxSpeed() targetSpeed = target.getSpeed() targetVelocity = target.getVelocity() agentToTarget = calculate.subtractPoints(targetPosition, agentPosition) distanceToTarget = vector.getMagnitude(agentToTarget) lookAheadTime = distanceToTarget / (agentMaxSpeed + targetSpeed) lookAheadVector = calculate.multiplyVectorAndScalar(targetVelocity, lookAheadTime) lookAheadPosition = calculate.addPointAndVector(targetPosition, lookAheadVector) return seek.seek(agent, lookAheadPosition)
def plotLocalRouteAroundTarget(owner, target): steeringController = owner.steeringController ownerPosition = owner.getPosition() targetPosition = target.getPosition() ownerToTarget = calculate.subtractPoints(targetPosition, ownerPosition) distanceToTarget = vector.getMagnitude(ownerToTarget) optimalPathDistance = min(distanceToTarget, owner.getMaximumFiringRange()) #These are the eight "compass" directions, projected #in the target's local space vectors = ((0, 1), (1, 1), (1, 0), (-1, 1), (-1, 0), (-1, -1), (0, -1), (1, -1)) #Now scale the directions so that they have my magnitude. #We can treat these vectors as points in an octagonal #path around the target - a path scaled to an optimal distance. pathPoints = [calculate.multiplyVectorAndScalar(normalizedVector, optimalPathDistance) for normalizedVector in vectors] #Find the point in the path that is closest to my position. ownerLocalPosition = convert.pointToLocalSpace(ownerPosition, targetPosition, target.getDirection()) closestDistanceSquared = None closestIndex = None for index in range(len(pathPoints)): pathPoint = pathPoints[index] ownerToPathPoint = calculate.subtractPoints(pathPoint, ownerLocalPosition) distanceSquaredToPathPoint =\ vector.getMagnitudeSquared(ownerToPathPoint) if (closestDistanceSquared is None or distanceSquaredToPathPoint < closestDistanceSquared): closestIndex = index closestDistanceSquared = distanceSquaredToPathPoint #Now "shift" the path so that my closest point is the first in the list. path = pathPoints[closestIndex:] + pathPoints[:closestIndex] #Plot a course to visit the path. If at any point I find a clear shot to the target, #I will dive at it. steeringController.plotPath(path, closed=True)
def _getObstaclesInRange(agent, obstacles): inRange = [] agentPosition = agent.getPosition() (obstacleDetectionLength, obstacleDetectionWidth) = agent.getObstacleDetectionDimensions() for obstacle in obstacles: parentToObstacle =\ calculate.subtractPoints(obstacle.getPosition(), agentPosition) if (vector.getMagnitude(parentToObstacle) <= obstacleDetectionLength + obstacle.getRadius()): inRange.append(obstacle) return inRange
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 update(self, timeElapsed): current_time = self.world.current_time if self.timeOfNormalColor and current_time < self.timeOfNormalColor: self.color = (random.random(), random.random(), random.random()) elif self.timeOfNormalColor: self.timeOfNormalColor = None self.color = self.normalColor world = self.world maxspeed = self.maxSpeed throttlespeed = self.throttleSpeed maxforce = self.maxForce minDetectionLength = self.minDetectionLength for stateMachine in self.stateMachines: stateMachine.update() for turret in self.turrets: turret.update(timeElapsed) self.launch() force = self.steeringController.calculate() force = vector.truncate(vectorTuple=force, cap=maxforce) acceleration = calculate.multiplyVectorAndScalar(vector=force, scalar=timeElapsed / (self.mass * 1000.0)) velocity = calculate.addVectors(self.velocity, acceleration) velocity = vector.truncate(velocity, throttlespeed) self.velocity = velocity speed = vector.getMagnitude(velocity) (x, y) = calculate.addPointAndVector(self.position, velocity) self.position = (x, y) self.obstacleDetectionDimensions[0] =\ minDetectionLength + (speed / maxspeed) * minDetectionLength
def evade(agent, target, evadeDistanceSquared=None): agentPosition = agent.getPosition() agentMaxSpeed = agent.getMaxSpeed() targetPosition = target.getPosition() targetSpeed = target.getSpeed() targetVelocity = target.getVelocity() targetToAgent = calculate.subtractPoints(agentPosition, targetPosition) distanceToTarget = vector.getMagnitude(targetToAgent) lookAheadTime = distanceToTarget / (agentMaxSpeed + targetSpeed) lookAheadVector = calculate.multiplyVectorAndScalar(targetVelocity, lookAheadTime) lookAheadPosition = calculate.addPointAndVector(targetPosition, lookAheadVector) return flee.flee(agent, lookAheadPosition, evadeDistanceSquared)
def interpose(agent, enemy, charge): agentPosition = agent.getPosition() agentMaxSpeed = agent.getMaxSpeed() enemyPosition = enemy.getPosition() enemyVelocity = enemy.getVelocity() chargePosition = charge.getPosition() chargeVelocity = charge.getVelocity() enemyToCharge = calculate.subtractPoints(chargePosition, enemyPosition) midVector = calculate.multiplyVectorAndScalar(enemyToCharge, .5) midPoint = calculate.addPointAndVector(enemyPosition, midVector) agentToMidPoint = calculate.subtractPoints(midPoint, agentPosition) distanceToMidPoint = vector.getMagnitude(agentToMidPoint) timeToMidPoint = distanceToMidPoint / agentMaxSpeed enemyToFuturePosition = calculate.multiplyVectorAndScalar(enemyVelocity, timeToMidPoint) enemyFuturePosition = calculate.addPointAndVector(enemyPosition, enemyToFuturePosition) chargeToFuturePosition = calculate.multiplyVectorAndScalar(chargeVelocity, timeToMidPoint) chargeFuturePosition = calculate.addPointAndVector(chargePosition, chargeToFuturePosition) enemyFutureToChargeFuture = calculate.subtractPoints(chargeFuturePosition, enemyFuturePosition) futureMidVector = calculate.multiplyVectorAndScalar(enemyFutureToChargeFuture, .5) futureMidPoint = calculate.addPointAndVector(enemyFuturePosition, futureMidVector) return arrive.arrive(agent, futureMidPoint)
def arrive(agent, targetPosition, decelerationFactor=None): steeringController = agent.getSteeringController() if decelerationFactor is None: decelerationFactor = steeringController.decelerationFactor agentPosition = agent.getPosition() agentToTarget = calculate.subtractPoints(targetPosition, agentPosition) distanceToTarget = vector.getMagnitude(agentToTarget) if round(distanceToTarget) > 0: agentMaxSpeed = agent.getMaxSpeed() agentVelocity = agent.getVelocity() speed = distanceToTarget / decelerationFactor speed = min(speed, agentMaxSpeed) desiredVelocity = calculate.multiplyVectorAndScalar(agentToTarget, speed / distanceToTarget) return calculate.subtractVectors(desiredVelocity, agentVelocity) else: return (0, 0)
def getSpeed(self): return vector.getMagnitude(self.velocity)
def __init__(self, position, length, width, velocity, color, render, world, mass, maxSpeed, maxForce, fleet, health, flightGroup=None, launchOffset=None, startingState=None, mission=None, globalState=None, targetingSystem=None, name=None): self.name = name self.length = length self.width = width self.lengthSquared = length * length self.widthSquared = width * width self.position = position self.velocity = velocity self.color = color self.normalColor = color self.timeOfNormalColor = None self.timeOfNextLaunch = None self.msBetweenLaunches = 3000 self.msOfShotColor = 200 self.maxSpeed = maxSpeed self.throttleSpeed = maxSpeed self.maxForce = maxForce self.world = world self.targetingSystem = targetingSystem self.steeringController = steeringcontroller.SteeringController(agent=self) self.mission = mission self.steeringStateMachine = statemachine.StateMachine( owner=self, currentState=None, globalState=None, name='steering') self.goalStateMachine = statemachine.StateMachine( owner=self, currentState=startingState, globalState=globalState, name='goal') self.stateMachines = [self.goalStateMachine, self.steeringStateMachine] self.flightGroup = flightGroup self.target = None self.render = render self.turrets = [] self.flightGroups = {'fighter' : [], 'bomber' : [], 'interceptor' : []} self.targettingTurrets = [] self.attackers = [] self.active = True self.fleet = fleet self.mass = mass self.minDetectionLength = 120 halfWidth = width / 2.0 halfLength = length / 2.0 self.hangarEntryThresholdSquared = 1000000 self.boundingBox = (halfLength, halfWidth, -halfLength, -halfWidth) speed = vector.getMagnitude(velocity) self.obstacleDetectionDimensions =\ [self.minDetectionLength + (speed / maxSpeed) * self.minDetectionLength, width] if launchOffset is None: launchOffset = (-halfWidth - 200, 0) self.launchOffset = launchOffset self.health = health self.totalHealth = health ''' debugObserver = world.frame.childFrames.get('%sDebug' % fleet.teamName) self.observers = [debugObserver] ''' self.observers = []
def test_allY(self): startVector = (0, 5) magnitude = vector.getMagnitude(startVector) self.assertEquals(5, magnitude)