Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def drawImages(self, axes):
""" Draw all images (real and virtual) of the object defined by
objectPosition, objectHeight """
(xScaling, yScaling) = self.axesToDataScaling(axes)
arrowWidth = xScaling * 0.01
arrowHeight = yScaling * 0.03
transferMatrix = Matrix(A=1, B=0, C=0, D=1)
matrices = self.transferMatrices()
for element in matrices:
transferMatrix = element * transferMatrix
(distance, conjugate) = transferMatrix.forwardConjugate()
if distance is not None:
imagePosition = transferMatrix.L + distance
if imagePosition != 0 and conjugate is not None:
magnification = conjugate.A
axes.arrow(
imagePosition,
-magnification * self.objectHeight / 2,
0,
(magnification) * self.objectHeight,
width=arrowWidth/5,
fc='r',
ec='r',
def transferMatrix(self, upTo=float('+Inf')):
""" The transfer matrix between front edge and distance=upTo
If "upTo" falls inside an element of finite length, then
it will request from that element a "partial" transfer matrix
for a fraction of the length. It is up to the Matrix() or
MatrixGroup() to define such partial transfer matrix when possible.
Quite simply, Space() defines a partial matrix as Space(d=upTo).
"""
transferMatrix = Matrix(A=1, B=0, C=0, D=1)
distance = upTo
for element in self.elements:
if element.L <= distance:
transferMatrix = element * transferMatrix
distance -= element.L
else:
transferMatrix = element.transferMatrix(upTo=distance) * transferMatrix
break
return transferMatrix
def isImaging(self):
"""If B=0, then the matrix is from a conjugate plane to another
(i.e. object at the front edge and image at the back edge).
In this case, A = transverse magnification, D = angular magnification
As usual, C = -1/f (always).
"""
return abs(self.B) < Matrix.__epsilon__
it does not do anything because they are the same either way. However,
subclasses can override this function and act accordingly.
"""
super(DielectricInterface, self).flipOrientation()
temp = self.n1
self.n1 = self.n2
self.n2 = temp
self.R = -self.R
self.C = - (self.n2-self.n1)/(self.n2*self.R)
self.D = self.n1/self.n2
return self
class ThickLens(Matrix):
"""A thick lens of first radius R1 and then R2, with an index n
and length d
A biconvex lens has R1 > 0 and R2 < 0.
"""
def __init__(self, n, R1, R2, thickness, diameter=float('+Inf'), label=''):
self.R1 = R1
self.R2 = R2
self.n = n
t = thickness
a = t*(1.0-n)/(n*R1) + 1
b = t/n
c = - (n - 1.0)*(1.0/R1 - 1.0/R2 + t*(n-1.0)/(n*R1*R2))
axes.arrow(position, size+arrowSize, 0, -arrowSize,
width=0.1, fc='g', ec='g',
head_length=arrowHeight, head_width=arrowWidth,
length_includes_head=True)
axes.arrow(position, -size-arrowSize, 0, arrowSize,
width=0.1, fc='g', ec='g',
head_length=arrowHeight, head_width=arrowWidth,
length_includes_head=True)
""" Synonym of Matrix: Element
We can use a mathematical language (Matrix) or optics terms (Element)
"""
Element = Matrix
Group = MatrixGroup
OpticalPath = ImagingPath
label=label)
def drawAt(self, z, axes, showLabels=False):
""" Draw nothing because free space is nothing. """
return
def transferMatrix(self, upTo=float('+Inf')):
""" Returns a Matrix() corresponding to a partial propagation
if the requested distance is smaller than the length of this element"""
distance = upTo
if distance < self.L:
return Space(distance)
else:
return self
class DielectricInterface(Matrix):
"""A dielectric interface of radius R, with an index n1 before and n2
after the interface
A convex interface from the perspective of the ray has R > 0
"""
def __init__(self, n1, n2, R=float('+Inf'),
diameter=float('+Inf'), label=''):
self.n1 = n1
self.n2 = n2
self.R = R
a = 1.0
b = 0.0
c = - (n2-n1)/(n2*R)
d = n1/n2
""" String description that allows the use of print(Matrix())
"""
description = "\n / \\ \n"
description += "| {0:6.3f} {1:6.3f} |\n".format(self.A, self.B)
description += "| |\n"
description += "| {0:6.3f} {1:6.3f} |\n".format(self.C, self.D)
description += " \\ /\n"
if self.C != 0:
description += "\nf={0:0.3f}\n".format(-1.0 / self.C)
else:
description += "\nf = +inf (afocal)\n"
return description
class Lens(Matrix):
"""A thin lens of focal f, null thickness and infinite or finite diameter
"""
def __init__(self, f, diameter=float('+Inf'), label=''):
super(Lens, self).__init__(A=1, B=0, C=-1 / float(f), D=1,
physicalLength=0,
apertureDiameter=diameter,
frontVertex=0,
backVertex=0,
label=label)
def drawAt(self, z, axes, showLabels=False):
""" Draw a thin lens at z """
halfHeight = self.displayHalfHeight() # real units, i.e. data