def draw( self, canvas ): heightHalf = self.height * 0.5 widthHalf = self.width * 0.5 xPlus = widthHalf xMinus = -widthHalf yPlus = heightHalf yMinus = -heightHalf # Point 0. x0 = rotation.rotateX( xMinus, yMinus, self.angle ) + self.x y0 = rotation.rotateY( xMinus, yMinus, self.angle ) + self.y # Point 1. x1 = rotation.rotateX( xPlus, yMinus, self.angle ) + self.x y1 = rotation.rotateY( xPlus, yMinus, self.angle ) + self.y # Point 2. x2 = rotation.rotateX( xPlus, yPlus, self.angle ) + self.x y2 = rotation.rotateY( xPlus, yPlus, self.angle ) + self.y # Point 3. x3 = rotation.rotateX( xMinus, yPlus, self.angle ) + self.x y3 = rotation.rotateY( xMinus, yPlus, self.angle ) + self.y # Draw. x0 = self.worldToScreenX( x0 ) y0 = self.worldToScreenY( y0 ) x1 = self.worldToScreenX( x1 ) y1 = self.worldToScreenY( y1 ) x2 = self.worldToScreenX( x2 ) y2 = self.worldToScreenY( y2 ) x3 = self.worldToScreenX( x3 ) y3 = self.worldToScreenY( y3 ) canvas.create_polygon( x0, y0, x1, y1, x2, y2, x3, y3, width = self.line, fill = self.fill, outline = self.color )
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 rect >>> from data import vector2d >>> c = circle.Circle() >>> c.position.x = -4 >>> c.position.y = 2 >>> c.radius = 2 >>> c.momentum = vector2d.Vector2d( 4, 2 ) >>> r = rect.Rect() >>> r.position.x = 0 >>> r.position.y = 2 >>> r.width = 4 >>> r.height = 4 >>> x = -2 >>> y = 2 >>> reflector = CircleRectReflector( c, r ) >>> v = reflector.reflect( x, y ) >>> print( '{0:.2f}, {1:.2f}'.format(v.x, v.y) ) -4.00, 2.00 ''' # Calculate values of all four points of the rectangle without rotation. heightHalf = self._rect.height * 0.5 widthHalf = self._rect.width * 0.5 xPlus = widthHalf xMinus = -widthHalf yPlus = heightHalf yMinus = -heightHalf # Rotate reflection point back and move to origin. rotatedX = rotation.rotateX( x - self._rect.position.x, y - self._rect.position.y, -self._rect.angle ) rotatedY = rotation.rotateY( x - self._rect.position.x, y - self._rect.position.y, -self._rect.angle ) # Prepare comparison. pointX1 = 0 pointY1 = 0 pointX2 = 0 pointY2 = 0 left, up, right = range(3) dists = [] dists.append( py.pointToLineDistance(rotatedX, rotatedY, xMinus, yMinus, xMinus, yPlus) ) dists.append( py.pointToLineDistance(rotatedX, rotatedY, xMinus, yPlus, xPlus, yPlus) ) dists.append( py.pointToLineDistance(rotatedX, rotatedY, xPlus, yMinus, xPlus, yPlus) ) dists.append( py.pointToLineDistance(rotatedX, rotatedY, xMinus, yMinus, xPlus, yMinus) ) line = dists.index( min(dists) ) # Left. if line is left: pointX1 = xMinus pointY1 = yMinus pointX2 = xMinus pointY2 = yPlus # Up. elif line is up: pointX1 = xMinus pointY1 = yPlus pointX2 = xPlus pointY2 = yPlus # Right. elif line is right: pointX1 = xPlus pointY1 = yMinus pointX2 = xPlus pointY2 = yPlus # Down. else: pointX1 = xMinus pointY1 = yMinus pointX2 = xPlus pointY2 = yMinus # Rotate line points. rotatedX1 = rotation.rotateX( pointX1, pointY1, self._rect.angle ) + self._rect.position.x rotatedY1 = rotation.rotateY( pointX1, pointY1, self._rect.angle ) + self._rect.position.y rotatedX2 = rotation.rotateX( pointX2, pointY2, self._rect.angle ) + self._rect.position.x rotatedY2 = rotation.rotateY( pointX2, pointY2, self._rect.angle ) + self._rect.position.y # Calculate result. x, y = vector.reflectAtLine( self._circle.momentum.x, self._circle.momentum.y, rotatedX1, rotatedY1, rotatedX2, rotatedY2 ) return vector2d.Vector2d( x, y )