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 )
Esempio n. 2
0
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