geoptics.elements package

Package contents

Package containing elements.

The physical scene is two-dimensional.

First, it has an infinite background region (air by default), and possibly contains several regions of different materials. Regions are defined in the regions submodule.

Second, sources emit rays of light. Rays must have a source, from the sources submodule.

Rays propagation takes place in the rays submodule.

The elements can be used alone, and form a consistent framework. But if a graphical representation is desired, the current preferred procedure is to start from the qt package.

Elements glossary

element
elements

Object living in a scene. It can be a physical element like a source or a region, or geometrical objects such as segments or arcs.

index
optical index
refractive index

Number characteristic of the propagation of light in a material. Currently only transparent materials are handled, so the index is real. For instance, silica glass has an index close to 1.5 in the visible range.

line
lines

Shorthand for half-line, defined by a starting Point and a Vector direction.

scene

Physical area where elements live.

z_value
z_values

The z_value determines the “altitude” of an element. Elements with a higher z_value are drawn on top. Elements with lower z_value can be hidden by elements with a higher z_value.

Submodules imports

The python standard syntax to import submodules is

>>> from geoptics.elements.scene import Scene
>>> from geoptics.elements.sources import Beam
>>> scene = Scene()
>>> beam = Beam(scene=scene)

To make guis modules more readable, another route is provided by GeOptics:

>>> from geoptics import elements
>>> scene = elements.scene.Scene()
>>> beam = elements.sources.Beam(scene=scene)

This is mostly useful in guis modules to easily distinguish the elements Beam from the local gui Beam (since the element name starts with elements.). In user scripts, this is not useful, and the previous way is preferred.

Submodules

geoptics.elements.arc module

Define an arc of a circle.

class geoptics.elements.arc.Arc(M1, M2, tangent)[source]

Bases: object

Arc of a circle.

Parameters:
  • M1 (Point) – starting point

  • M2 (Point) – ending point

  • tangent (Vector) – tangent to the arc at the starting point M1

__contains__(M)[source]

Return True if the point M belongs to the arc sector.

Distances are not checked.

_get_ccw()[source]

Return true if the arc goes from M1 to M2 ccw.

center()[source]

Return the arc center.

property config

Configuration dictionary.

intersection(other, sign_of_s=0)[source]

Intersections of the arc with another element.

Parameters:
  • other (Line) – another element (as of v0.18, it must be a Line)

  • sign_of_s (int) – if sign_of_s !=0, consider other as a half line. i.e. s_other must have the same sign as sign_of_s or intersection will be empty

Returns:

list of intersections

Return type:

list of Intersection

radius()[source]

Return the arc radius of curvature.

translate(**kwargs)[source]

Translate the segment as a whole.

Same syntax and same side effects as geoptics.elements.vector.Point.translate()

Likewise, it is possible to insert a .copy() to avoid side-effects. FIXME: copy() not implemented yet…

Returns:

self, for convenience

Examples

>>> from geoptics.elements.vector import Point, Vector
>>> M1 = Point(110, 190)
>>> M2 = Point(120, 60)
>>> tg = Vector(10, -20)
>>> arc = Arc(M1, M2, tg)
>>> arc.C
Point(-44.54545454545456, 112.72727272727272)
>>> tr = Vector(5, 15)
>>> arc.translate(dv=tr)
>>> arc.M1
Point(115, 205)
>>> arc.M2
Point(125, 75)
>>> arc.C
Point(-39.54545454545456, 127.72727272727272)

geoptics.elements.line module

Define Lines.

class geoptics.elements.line.Intersection(p: Point, s: float, eN: Vector, eT: Vector)[source]

Bases: NamedTuple

Intersection between a Line and another element

_asdict()

Return a new dict which maps field names to their values.

_field_defaults = {}
_fields = ('p', 's', 'eN', 'eT')
classmethod _make(iterable)

Make a new Intersection object from a sequence or iterable

_replace(**kwds)

Return a new Intersection object replacing specified fields with new values

eN: Vector

unit vector normal to the other element, at the intersection

eT: Vector

unit vector tangent to the other element, at the intersection

p: Point

point of intersection

s: float

s multiplier of the Line (p0, u0), such that p = p0 + u0 * s

class geoptics.elements.line.Line(p=None, u=None)[source]

Bases: object

Line defined by a point p and a direction vector u.

Parameters:
  • p (Point) – Reference point belonging to the line

  • u (Vector) – Direction vector

property config

Configuration dictionary.

copy()[source]

Return an independent copy.

classmethod from_config(config)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Line instance

Return type:

Line

Examples

>>> from geoptics.elements.vector import Point, Vector
>>> p = Point(10, 20)
>>> u = Vector(30, 60)
>>> line1 = Line(p, u)
>>> config = line1.config
>>> line2 = Line.from_config(config)
>>> line2.config == config
True
static interpolate(line_start, line_end, x)[source]

Interpolated line.

The returned line is interpolated between two given lines, going ccw from line_start to line_end.

The interpolation is done on Line.p and on the Line.u angle.

Parameters:
  • line_start (Line) – The starting line.

  • line_end (Line) – The ending line.

  • x (float) – the fraction, between 0.0 (starting line) and 1.0 (ending line).

Returns:

Interpolated line.

Return type:

Line

intersection(other, sign_of_s=0)[source]

Intersections of the line with another line.

Parameters:
  • other (Line) – another line.

  • sign_of_s (float) – if sign_of_s !=0, consider other as a half line, and search for intersections with s having the same sign as sign_of_s.

Returns:

list either empty (no intersection), or holding a single intersection.

This is done for consistency with other elements that can have multiple intersections with a line.

Return type:

list of Intersection

normal(normalized=False)[source]

Return a vector orthogonal to the line.

Parameters:

normalized (bool) – if True, return a unit vector.

Returns:

Vector

point(s)[source]

Return the Point at the position p + s * u.

tangent(normalized=False)[source]

Return a tangent vector to the line.

For a line, this is basically u itself.

Parameters:

normalized (bool) – if True, return a unit vector.

Returns:

Vector

translate(**kwargs)[source]

Translate the starting point.

Same syntax and same side effects as geoptics.elements.vector.Point.translate()

Likewise, it is possible to insert a .copy() to avoid side-effects.

return self for convenience

geoptics.elements.rays module

Rays of light.

Part should not be used directly. Actually, even Ray should not be used directly. Users wanting a single ray should instanciate a SingleRay source.

class geoptics.elements.rays.Part(line=None, s=None, n=None)[source]

Bases: object

Straight part of a ray.

property config

Configuration dictionary.

classmethod from_config(config)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Part instance

Return type:

Part

Examples

>>> from geoptics.elements.vector import Point, Vector
>>> from geoptics.elements.line import Line
>>> from geoptics.elements.rays import Ray
>>> p = Point(10, 20)
>>> u = Vector(30, 60)
>>> line1 = Line(p, u)
>>> s = 100
>>> n = 1.5
>>> part1 = Part(line1, s, n)
>>> config = part1.config
>>> part2 = Part.from_config(config)
>>> part2.config == config
True
line

starting point and direction

n

optical index

s

length

translate(**kwargs)[source]

Translate the part as a whole.

Same syntax and same side effects as geoptics.elements.vector.Point.translate()

Likewise, it is possible to insert a .copy() to avoid side-effects. FIXME: copy() not implemented yet…

return self for convenience

class geoptics.elements.rays.Ray(line0=None, s0=100, source=None, n=None, tag=None)[source]

Bases: object

A ray of light.

A ray must have a source. normally rays are not created directly. Use one of the sources module objects instead.

Parameters:
  • line0 (Line) – first point and direction

  • s0 (float) – initial length

  • n (float) – refractive index of the starting medium

  • source (Source) – source of the ray

add_part(u, s, n=None)[source]

Add a new part to the ray.

Parameters:
  • u (Line) – starting point and direction for that part

  • s (float) – length of that part

  • n (float, optional) – optical index encountered by that part.

change_line_0(line)[source]

Change the ray starting line.

change_s(part_index, new_s)[source]

Change the length of one of the ray parts.

Parameters:
  • part_index (int) – the index of the part to alter

  • new_s (float) – the new length pf that part

property config

Configuration dictionary.

draw()[source]

Draw the ray.

This method does nothing in the elements realm, but should be overloaded is there is a graphical counterpart In this case, the ray should be (re)drawn

classmethod from_config(config, source=None, tag=None)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Part instance

Return type:

Part

Examples

>>> from geoptics.elements.vector import Point, Vector
>>> from geoptics.elements.line import Line
>>> from geoptics.elements.rays import Ray
>>> p = Point(10, 20)
>>> u = Vector(30, 60)
>>> line1 = Line(p, u)
>>> s = 100
>>> n = 1.5
>>> ray1 = Ray(line0=line1, s0=s, n=n)
>>> config = ray1.config
>>> ray2 = Ray.from_config(config)
>>> ray2.config == config
True
move_p0(dx, dy)[source]

Translate the ray starting point, leaving the direction unchanged.

propagate(scene)[source]

Propagate ray across scene.

set_tag(tag)[source]

Set tag.

translate(**kwargs)[source]

Translate the ray as a whole.

Same syntax and same side effects as geoptics.elements.vector.Point.translate()

Likewise, it is possible to insert a .copy() to avoid side-effects. FIXME: copy() not implemented yet…

return self for convenience

geoptics.elements.regions module

Define regions.

Specific region classes should inherit from the generic Region.

Currently an all-purpose Polycurve is available.

class geoptics.elements.regions.Polycurve(n=None, scene=None, tag=None)[source]

Bases: Region

Define a region inside curves (line segments, arcs, …).

Parameters:
Returns:

a region

Return type:

Region

add_arc(M_next, tangent)[source]

Add an Arc curve to the boundary.

The arc starts from the last point with the given tangent, and ends on M_next.

add_line(M_next)[source]

Add a straight section to the region boundary.

The added section is actually a Segment, between the last point and the given M_next point.

close()[source]

Join the last point to the first point with a segment.

property config

Configuration dictionary.

classmethod from_config(config, scene=None, tag=None)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Polycurve instance

Return type:

Polycurve

intersection(other, sign_of_s=0)[source]

Return the intersections between the region boundaries and other.

Args: same as elements.segment.Segment.intersection()

start(M_start)[source]

Initialize the region boundary.

Set the starting point to M_start

translate(**kwargs)[source]

Translate the region as a whole.

Same syntax and same side effects as geoptics.elements.vector.Point.translate()

Likewise, it is possible to insert a .copy() to avoid side-effects. FIXME: copy() not implemented yet…

Return self for convenience

class geoptics.elements.regions.Region(n=None, scene=None)[source]

Bases: object

Region of space.

contains(point=None, u=None, line=None)[source]

Is a given point contained in this region ?

Alternatively, line can be given, in which case point is taken from line.p, and u from line.u.

Parameters:
  • point (Point) – The point of interest

  • u (Vector) – Searching direction

  • line (Line) – Contains both point and searching direction (see above)

intersection(other, sign_of_s=0)[source]

Return the intersections between the region boundaries and other.

By default, return an empty list. This method should be overloaded by specific region classes.

Args: same as elements.segment.Segment.intersection()

n

optical index

scene

physical scene where the region will be placed

geoptics.elements.scene module

Define a Scene, and hold all the propagation calculations.

class geoptics.elements.scene.Scene[source]

Bases: object

Scene holding all items.

_add_config(config)[source]

Add regions and sources from a configuration dictionary.

_add_iterator(config)[source]

Return an iterator over the available items in config.

add(other)[source]

Add an element to the scene.

Parameters:

other

the element to add to the scene. The element can be a Source or a Region.

A Ray is also accepted, for internal use, but normal users should only add Sources or Regions.

background

background medium (air by default)

clear()[source]

Remove all regions and sources.

property config

Configuration dictionary.

classmethod from_config(config)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Scene instance

Return type:

Scene

propagate(rays=None)[source]

Propagate rays from sources, across regions.

region_at(*args, **kwargs)[source]

Return the region where the given point belongs to.

In case of overlapping self.regions, return the first one found.

Args: same as meth:geoptics.elements.regions.Region.contains

Returns:

the region point belongs to.

(or self.background if inside no region)

Return type:

Region

regions

list of all regions, excluding background

remove(other)[source]

Remove element from scene.

sources

list of all sources

geoptics.elements.segment module

Define a geometric Segment [M1, M2].

class geoptics.elements.segment.Segment(M1, M2)[source]

Bases: object

Segment defined by its two ends: M1 et M2.

Parameters:
  • M1 (Point) – first end

  • M2 (Point) – second end

property config

Configuration dictionary.

intersection(other, sign_of_s=0)[source]

Intersections of the segment with another element.

Parameters:
  • other (Line) – another element (as of v0.18, it must be a Line)

  • sign_of_s (int) – if sign_of_s !=0, consider other as a half line. i.e. s_other must have the same sign as sign_of_s or intersection will be empty

Returns:

list of intersections

Return type:

list of Intersection

middle()[source]

Return the middle of the segment.

normal(normalized=False)[source]

Return a normal to the segment.

Parameters:

normalized (bool) – if True, return a unit vector.

Returns:

Vector

translate(**kwargs)[source]

Translate the segment as a whole.

Same syntax and same side effects as geoptics.elements.vector.Point.translate()

Likewise, it is possible to insert a .copy() to avoid side-effects. FIXME: copy() not implemented yet…

return self for convenience

geoptics.elements.sources module

Sources of light rays.

This is the correct way for a user to generate and control rays.

Currently available sources are:

  • SingleRay for a single ray (surprise !)

  • Beam for a beam of light with evenly spaced rays. The Beam is very generic. Rays can be diverging, parallel, or focused. The source can be extended or point-like.

class geoptics.elements.sources.Beam(line_start=None, s_start=None, line_end=None, s_end=None, N_inter=0, scene=None, tag=None)[source]

Bases: Source

Beam of rays.

The Beam is defined by two extreme rays (first and last). Intermediate rays positions and angles (lines) are evenly interpolated between the first and last ray.

Parameters:
  • line_start (Line) – starting line for the beam first ray

  • line_end (Line) – starting line for the beam last ray

  • s_start (float) – initial length of the beam first ray

  • s_end (float) – initial length of the beam last ray

  • N_inter (int) – number of intermediate rays (>= 0)

  • scene (Scene) –

Returns:

Source with N_inter + 2 (first and last) rays.

classmethod from_config(config, scene=None, tag=None)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Beam instance

Return type:

Beam

set(line_start=None, line_end=None, s_start=None, s_end=None, N_inter=None)[source]

Set beam parameters.

The parameters are taken from the given arguments, or from existing rays if the corresponding argument is missing

Args: same as Beam, except ‘scene’ (for now)

class geoptics.elements.sources.SingleRay(line0=None, s0=None, scene=None, tag=None)[source]

Bases: Source

Single ray source.

Parameters:

line0 (Line) – starting

change_line_0(line)[source]

Change the starting line of the ray.

move_p0(dx, dy)[source]

Translate the starting point of the ray.

class geoptics.elements.sources.Source(scene=None, tag=None)[source]

Bases: object

Source of rays.

Parameters:

scene (Scene) –

property config

Configuration dictionary.

classmethod from_config(config, scene=None, tag=None)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Source instance

Return type:

Source

translate(**kwargs)[source]

Translate the source as a whole.

Same syntax and same side effects as geoptics.elements.vector.Point.translate()

Likewise, it is possible to insert a .copy() to avoid side-effects. FIXME: copy() not implemented yet…

return self for convenience

geoptics.elements.vector module

Points and vectors in 2D.

class geoptics.elements.vector.Point(x=None, y=None)[source]

Bases: object

2D point.

property config

Configuration dictionary.

copy()[source]

Return an independent copy of the point.

classmethod from_config(config)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Point instance

Return type:

Point

Examples

>>> v1 = Point(10, 20)
>>> config = v1.config
>>> v2 = Point.from_config(config)
>>> v2.config == config
True
translate(dv=None, dx=0, dy=0)[source]

Translate the point.

The translation must be given as a single vector (dv) or with dx and/or dy. If dv is given, dx and dy are discarded.

For example:

>>> p = Point(30, 50)
>>> dv = Vector(x=10, y=20)
>>> p.translate(dv)
Point(40, 70)

is the same as:

>>> p = Point(30, 50)
>>> p.translate(dx=10, dy=20)
Point(40, 70)
It is possible to change only one coordinate
>>> p = Point(30, 50)
>>> p.translate(dx=10)
Point(40, 50)

Beware that the transformation is done in-place. this can lead to side effects. For example, in order to leave p1 untouched, a .copy() has to be inserted:

>>> p2 = p.copy().translate(dx=10, dy=20)
Parameters:
  • dv (Vector, optional) – Translation vector

  • dx (number, optional) – Translation amount along x

  • dy (number, optional) – Translation amount along y

Returns:

The point has been modified in-place, but for convenience, the point itself is also returned

Return type:

Point

x
y
class geoptics.elements.vector.Vector(x, y)[source]

Bases: object

2D Vector.

colinear(other)[source]

Return True if self and other are colinear.

property config

Configuration dictionary.

copy()[source]

Return an independent copy of the vector.

classmethod from_config(config)[source]

Alternate constructor.

Parameters:

config (dict) – Configuration dictionary

Returns:

new Vector instance

Return type:

Vector

Examples

>>> v1 = Vector(10, 20)
>>> config = v1.config
>>> v2 = Vector.from_config(config)
>>> v2.config == config
True
norm()[source]

Return the vector norm.

normal(normalized=False)[source]

Return a vector orthogonal to self.

normalize()[source]

Normalize vector (divide it by its norm.

The normalization is done in-place, but also return self, for convenience.

theta_x()[source]

Return the inclination angle over the x axis.

Result in the ]-pi, pi] interval.

x
y
class geoptics.elements.vector.Vector_M1M2(M1, M2)[source]

Bases: Vector

Vector joining M1 to M2.

Parameters:
  • M1 (Point) – starting point

  • M2 (Point) – end point