def getLineSegmentIntersection(line1, line2): if linesAreParallel(line1, line2): return None A, B = line1 C, D = line2 bVector = calculate.subtractPoints(B, A) dVector = calculate.subtractPoints(D, C) cVector = calculate.subtractPoints(C, A) bperp = vector.getRightPerpendicular(bVector) dperp = vector.getRightPerpendicular(dVector) dperpDotB = calculate.dotProduct(dperp, bVector) dperpDotC = calculate.dotProduct(dperp, cVector) bperpDotC = calculate.dotProduct(bperp, cVector) distanceAlongB = float(dperpDotC) / float(dperpDotB) distanceAlongD = float(bperpDotC) / float(dperpDotB) if (distanceAlongB > 0 and distanceAlongB < 1 and distanceAlongD > 0 and distanceAlongD < 1): AToIntersectionPoint = calculate.multiplyVectorAndScalar(bVector, distanceAlongB) intersectionPoint = calculate.addPointAndVector(A, AToIntersectionPoint) return intersectionPoint else: return None
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 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 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 pointInRectangle(point, rectangle): a, b, c, d = rectangle ap = calculate.subtractPoints(point, a) ab = calculate.subtractPoints(b, a) ad = calculate.subtractPoints(d, a) return ( 0 <= calculate.dotProduct(ap, ab) <= calculate.dotProduct(ab, ab) and 0 <= calculate.dotProduct(ap, ad) <= calculate.dotProduct(ad, ad))
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 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 linesAreParallel(line1, line2): A, B = line1 C, D = line2 ab_vector = calculate.subtractPoints(B, A) cd_vector = calculate.subtractPoints(D, C) cd_perp = vector.getRightPerpendicular(cd_vector) cdperp_dot_ab = calculate.dotProduct( cd_perp, ab_vector) return cdperp_dot_ab == 0
def enter(cls, owner): owner.update_path() path = owner.get_path() next_tile = owner.get_current_tile() while next_tile is owner.get_current_tile(): if len(path) == 0: raise statemachine.StateChangeFailed() next_tile = path.pop(0) if next_tile.is_obstructed(): raise statemachine.StateChangeFailed() owner_to_tile = calculate.subtractPoints(next_tile.getPosition(), owner.getPosition()) # Pick the cardinal direction that's closest to the # force vector cardinal_velocity = vector.pick_closest_vector(owner_to_tile, [(0, 1), (0, -1), (-1, 0), (1, 0)]) owner.set_next_tile(next_tile) owner.setVelocity( vector.setMagnitude(cardinal_velocity, owner.single_speed))
def test_firstArgumentIsLargerThanFirst_returnPositiveVector(self): vector1 = (3, 3) vector2 = (1, 1) resultVector = calculate.subtractPoints(vector1, vector2) self.assertEquals((2, 2), resultVector)
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 update(self, timeElapsed): world = self.world currentPosition = self.position shipHit = self.hit() if shipHit: shipHit.hitBy(self) world.removeShot(self) self.active = False return originToCurrent = calculate.subtractPoints(currentPosition, self.startingPosition) distanceSquaredFromOrigin = vector.getMagnitudeSquared(originToCurrent) if distanceSquaredFromOrigin > self.maxDistanceSquared: world.removeShot(self) return (x, y) = calculate.addPointAndVector(currentPosition, self.velocity) self.position = (x, y)
def test_firstArgumentIsLargerThanFirst_returnNegativeVector(self): point1 = (3, 3) point2 = (1, 1) resultVector = calculate.subtractPoints(point1, point2) self.assertEquals((2, 2), resultVector)
def test_firstArgumentIsSmallerThanFirst_returnPositiveVector(self): point1 = (1, 1) point2 = (3, 3) resultVector = calculate.subtractPoints(point1, point2) self.assertEquals((-2, -2), resultVector)
def test_twoZeroVectors_vectorIsZero(self): vector1 = (0, 0) vector2 = (0, 0) resultVector = calculate.subtractPoints(vector1, vector2) self.assertEquals((0, 0), resultVector)
def test_pointMinusSamePoint_vectorIsZero(self): point1 = (1, 1) point2 = (1, 1) resultVector = calculate.subtractPoints(point1, point2) self.assertEquals((0, 0), resultVector)
def test_vectorMinusSameVector_vectorIsZero(self): vector1 = (1, 1) vector2 = (1, 1) resultVector = calculate.subtractPoints(vector1, vector2) self.assertEquals((0, 0), resultVector)
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 test_firstArgumentIsSmallerThanFirst_returnNegativeVector(self): vector1 = (1, 1) vector2 = (3, 3) resultVector = calculate.subtractPoints(vector1, vector2) self.assertEquals((-2, -2), resultVector)
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 test_originMinusOrigin_vectorIsZero(self): point1 = (0, 0) point2 = (0, 0) resultVector = calculate.subtractPoints(point1, point2) self.assertEquals((0, 0), resultVector)
def acquireTemporaryTarget(self): '''Collect any targets that are in range. Then, collect from those the targets to which we have a clear shot. Find the one that is closest. That is the temporary target.''' turretPosition = self.getPosition() owner = self.owner fleet = owner.fleet enemiesInRange = [] for enemyShip in fleet.getAllEnemyShips(): if not self.targetIsInRange(enemyShip): continue if not self.haveClearShotOfTarget(enemyShip): continue enemiesInRange.append(enemyShip) closestShip = None closestDistanceSquared = None for enemyShip in enemiesInRange: enemyPosition = enemyShip.getPosition() turretToEnemy = calculate.subtractPoints(enemyPosition, turretPosition) distanceSquaredToEnemy = vector.getMagnitudeSquared(turretToEnemy) if closestShip is None or distanceSquaredToEnemy < closestDistanceSquared: closestShip = enemyShip closestDistanceSquared = distanceSquaredToEnemy if closestShip: self.setTarget(closestShip) return closestShip else: return None
def fire(self, target): owner = self.owner world = owner.world position = self.getPosition() speed = owner.getSpeed() shotSpeed = speed + self.shotSpeed predictedPosition = self.predictFuturePosition(source=self, target=target, shotSpeed=shotSpeed) shotToPredictedPosition = calculate.subtractPoints(predictedPosition, position) shotVelocity = vector.setMagnitude(shotToPredictedPosition, shotSpeed) shot = Shot(fromTurret=self, velocity=shotVelocity, position=position, maxDistance=self.firingRange, render=self.shotRenderer, height=self.shotHeight, width=self.shotWidth, color=(1, 1, 1), world=world, damage=self.damage, target=target) world.addShot(shot) self.timeRecharged = world.current_time + self.rechargeTime
def circleWithCircle(circle1, circle2): position_1, radius_1 = circle1 position_2, radius_2 = circle2 circle1_to_circle2 = calculate.subtractPoints(position_2, position_1) bounding_distance_squared = (radius_1 ** 2) + (radius_2 ** 2) actual_distance_squared = vector.getMagnitudeSquared( circle1_to_circle2) return actual_distance_squared < bounding_distance_squared
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 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 execute(cls, owner): motherShip = owner.fleet.motherShip ownerPosition = owner.getPosition() targetPosition = motherShip.getPosition() ownerToTarget = calculate.subtractPoints(targetPosition, ownerPosition) distanceSquaredToTarget = vector.getMagnitudeSquared(ownerToTarget) if distanceSquaredToTarget <= motherShip.hangarEntryThresholdSquared: motherShip.pickup(owner)
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 withinFiringRange(owner, target): ownerPosition = owner.getPosition() targetPosition = target.getPosition() ownerToTarget = calculate.subtractPoints(targetPosition, ownerPosition) distanceSquaredToTarget = vector.getMagnitudeSquared(ownerToTarget) if distanceSquaredToTarget < owner.getMaximumFiringRangeSquared(): return True else: return False
def pastBreakThreshold(owner, target): targetPosition = target.getPosition() ownerPosition = owner.getPosition() ownerToTarget = calculate.subtractPoints(targetPosition, ownerPosition) distanceSquaredToTarget = vector.getMagnitudeSquared(ownerToTarget) if distanceSquaredToTarget > breakThresholdSquared: return True else: return False
def seek(agent, targetPosition): maxSpeed = agent.getMaxSpeed() agentPosition = agent.getPosition() agentVelocity = agent.getVelocity() agentToTarget = calculate.subtractPoints(targetPosition, agentPosition) desiredVelocity = vector.setMagnitude(agentToTarget, maxSpeed) return calculate.subtractVectors(desiredVelocity, agentVelocity)