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 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 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 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 test_vectorsAreFacingInOppositeDirections(self): vector1 = (1, 0) vector2 = (-1, 0) dotProduct = calculate.dotProduct(vector1, vector2) self.assertEquals(-1, dotProduct)
def test_minus90degrees_dotProductIs0(self): vector1 = (1, 0) vector2 = (0, -1) dotProduct = calculate.dotProduct(vector1, vector2) self.assertEquals(0, dotProduct)
def test_vectorsAreTheSame_dotProductIs1(self): vector1 = (1, 0) vector2 = (1, 0) dotProduct = calculate.dotProduct(vector1, vector2) self.assertEquals(1, dotProduct)
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 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 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