Source code for cxroots.contours.Rectangle

import numpy as np
from scipy import pi

from ..Contour import Contour
from ..Paths import ComplexLine, ComplexArc

[docs]class Rectangle(Contour): """ A positively oriented rectangle in the complex plane. Parameters ---------- xRange : tuple Tuple of length two giving the range of the rectangle along the real axis. yRange : tuple Tuple of length two giving the range of the rectangle along the imaginary axis. Examples -------- .. plot:: :include-source: from cxroots import Rectangle rect = Rectangle(xRange=(-2, 2), yRange=(-1, 1)) rect.show() """ def __init__(self, xRange, yRange): self.xRange = xRange self.yRange = yRange self.axisName = ('x', 'y') self.z1 = z1 = self.xRange[0] + 1j*self.yRange[0] self.z2 = z2 = self.xRange[1] + 1j*self.yRange[0] self.z3 = z3 = self.xRange[1] + 1j*self.yRange[1] self.z4 = z4 = self.xRange[0] + 1j*self.yRange[1] segments = [ComplexLine(z1,z2), ComplexLine(z2,z3), ComplexLine(z3,z4), ComplexLine(z4,z1)] super(Rectangle, self).__init__(segments) def __str__(self): return 'Rectangle: vertices = {z1.real:.3f}{z1.imag:+.3f}i, {z2.real:.3f}{z2.imag:+.3f}i, {z3.real:.3f}{z3.imag:+.3f}i, {z4.real:.3f}{z4.imag:+.3f}i'.format(z1=self.z1, z2=self.z2, z3=self.z3, z4=self.z4) @property def centralPoint(self): # get the central point within the contour x = (self.xRange[0] + self.xRange[1])/2 y = (self.yRange[0] + self.yRange[1])/2 return x + 1j*y @property def area(self): return (self.xRange[1]-self.xRange[0])*(self.yRange[1]-self.yRange[0]) def contains(self, z): """ Returns True if the point z lies within the contour, False if otherwise """ return self.xRange[0] < z.real < self.xRange[1] and self.yRange[0] < z.imag < self.yRange[1] def subdivide(self, axis, divisionFactor=0.5): """ Subdivide the contour Parameters ---------- axis : str, can be either 'x' or 'y' The axis along which the line subdividing the contour is a constant. divisionFactor : float in range (0,1), optional Determines the point along 'axis' at which the line dividing the contour is placed. Returns ------- box1 : Rectangle If axis is 'x' then box1 has the same yRange and minimum value of xRange as the original Rectangle but the maximum xRange is determined by the divisionFactor. If axis is 'y' then box1 has the same xRange and minimum value of yRange as the original Rectangle but the maximum yRange is determined by the divisionFactor. box2 : Rectangle If axis is 'x' then box2 has the same yRange and maximum value of xRange as the original Rectangle but the minimum xRange is equal to the maximum xRange of box1. If axis is 'x' then box2 has the same xRange and maximum value of yRange as the original Rectangle but the minimum yRange is equal to the maximum yRange of box1. """ if axis == 'x' or self.axisName[axis] == 'x': midpoint = self.xRange[0] + divisionFactor*(self.xRange[1]-self.xRange[0]) box1 = Rectangle([self.xRange[0], midpoint], self.yRange) box2 = Rectangle([midpoint, self.xRange[1]], self.yRange) box1.segments[3] = self.segments[3] box2.segments[1] = self.segments[1] box1.segments[1]._reversePath = box2.segments[3] box2.segments[3]._reversePath = box1.segments[1] elif axis == 'y' or self.axisName[axis] == 'y': midpoint = self.yRange[0] + divisionFactor*(self.yRange[1]-self.yRange[0]) box1 = Rectangle(self.xRange, [self.yRange[0], midpoint]) box2 = Rectangle(self.xRange, [midpoint, self.yRange[1]]) box1.segments[0] = self.segments[0] box2.segments[2] = self.segments[2] box1.segments[2]._reversePath = box2.segments[0] box2.segments[0]._reversePath = box1.segments[2] for box in [box1, box2]: box._createdBySubdivisionAxis = axis box._parentBox = self self._childBoxes = [box1, box2] return box1, box2 def randomPoint(self): """Returns a random point inside the contour of the Rectangle.""" x = np.random.uniform(*self.xRange) y = np.random.uniform(*self.yRange) return x + 1j*y