def reflect( self, x, y ): ''' Calculates reflection between two circles. Returns the resulting momentum vector. Takes the position of the reflection point as argument. Test: >>> from data import circle >>> from data import vector2d >>> c1 = circle.Circle() >>> c1.position.x = -4 >>> c1.position.y = 2 >>> c1.radius = 2 >>> c1.momentum = vector2d.Vector2d( 4, 2 ) >>> c2 = circle.Circle() >>> c2.position.x = 0 >>> c2.position.y = 2 >>> c2.radius = 2 >>> x = -2 >>> y = 2 >>> reflector = CircleCircleReflector( c1, c2 ) >>> v = reflector.reflect( x, y ) >>> print( '{0:.2f}, {1:.2f}'.format(v.x, v.y) ) -4.00, 2.00 ''' # Move reflection point to origin. reflectionX = x - self._circle2.position.x reflectionY = y - self._circle2.position.y # Prepare comparison. epsilon = 0.001 # Default values are used it the tangent line is vertical. pointX1 = reflectionX pointY1 = -1 pointX2 = reflectionX pointY2 = 1 # Calculate tangent line y = mx + b if not comparison.floatEqual( reflectionY, 0, epsilon ): # Tangent line is perpendicular to the radius, so it's slope m will be a negative reciprocal # of the slope of the line intersecting the reflection point. m = -(reflectionX / reflectionY) # Find b with the slope and the reflection point. Default value is used if tangent line is # horizontal. b = reflectionY if not comparison.floatEqual( reflectionX, 0, epsilon ): b = reflectionY / (m * reflectionX) # Calculate tangent line points left and right of reflection point. pointX1 = reflectionX - 1 pointY1 = m * pointX1 + b pointX2 = reflectionX + 1 pointY2 = m * pointX2 + b # Calculate result. x, y = vector.reflectAtLine( self._circle1.momentum.x, self._circle1.momentum.y, pointX1, pointY1, pointX2, pointY2 ) return vector2d.Vector2d( x, y )
def reflectAtLine( x1, y1, x2, y2, x3, y3 ): ''' Reflects vector 1 at the line between vectors 2 and 3. Returns the x-component and y-component of the reflected vector in this order: reflectAtLine() => x, y Parameter: x1 -- The x-coordinate of the vector to reflect. y1 -- The y-coordinate of the vector to reflect. x2 -- The x-coordinate of the first point of the line. y2 -- The y-coordinate of the first point of the line. x3 -- The x-coordinate of the second point of the line. y3 -- The y-coordinate of the second point of the line. Test: >>> x, y = reflectAtLine( -2, -7, -2, 3, 4, -2 ) >>> print( '{0:.2f}, {1:.2f}'.format(x, y) ) 6.52, 3.23 >>> x, y = reflectAtLine( -4, 2, 0, -2, 0, 2 ) >>> print( '{0:.2f}, {1:.2f}'.format(x, y) ) 4.00, 2.00 ''' # Vector between both points aka the line. dx = x3 - x2 dy = y3 - y2 # Calculate normal with unit length. length = pythagorean.solveC( dy, dx ) nx = -dy ny = dx if not comparison.floatEqual( length, 0, 0.00001 ): nx /= length ny /= length # Dot product of vector 1 and normal. dotProduct = x1 * nx + y1 * ny # The reflected vector. x = x1 - 2 * nx * dotProduct y = y1 - 2 * ny * dotProduct return x, y