Beispiel #1
0
def creation(scene, creation_type):
	if creation_type == "direct creation":
		# une region
		m1 = Point(70, 60)
		# refractive index for rp1
		n = 1.5
		rp1 = regions.Polycurve(n=n, scene=scene)
		rp1.start(m1)
		m2 = Point(70, 190)
		rp1.add_line(m2)
		m3 = Point(110, 190)
		rp1.add_line(m3)
		m4 = Point(110, 60)
		tg4 = Vector(10, -20)
		#rp1.add_line(m4)
		rp1.add_arc(m4, tg4)
		rp1.close()
		del rp1
		
		p0 = Point(10, 20)
		u0 = Vector(108, 50)
		s0 = 3
		line0 = Line(p0, u0)
		source1 = sources.SingleRay(line0=line0, s0=s0, scene=scene)
		del line0
		del source1
		gc.collect()
		# !! comment ou this line => no crash !!
		scene.propagate()
	elif creation_type == "scene.load":
		filename = 'tests/shifted_polycurves+single_ray.geoptics'
		with open(filename, 'r') as f:
			config = yaml.safe_load(stream=f)
			logger.debug("config: {}".format(config))
			scene.clear()
			scene_config = config['Scene']
			scene.config = scene_config
			#gui.scene.load(config['Scene'])
			scene.propagate()
	elif creation_type == "load individually":
		filename = 'tests/shifted_polycurves+single_ray.geoptics'
		with open(filename, 'r') as f:
			config = yaml.safe_load(stream=f)
		config_rp1 = config['Scene']['Regions'][0]
		logger.debug("config: {}".format(config_rp1))
		rp1 = regions.Polycurve.from_config(config=config_rp1, scene=scene)
		del rp1
		#gc.collect()
		#qapp.processEvents()
		config_source1 = config['Scene']['Sources'][0]
		logger.debug("{}".format(config_source1['rays'][0]))
		source1 = sources.SingleRay.from_config(  # noqa: F841
		                                        config=config_source1,
		                                        scene=scene)
		logger.debug("{}".format(scene.sources))
		del source1
		gc.collect()
		#qapp.processEvents()
		# !! comment out this line => no crash !!
		scene.propagate()
Beispiel #2
0
 def __init__(self, p=None, u=None):
     if p is None:
         self.p = Point(x=0, y=0)
     else:
         self.p = p.copy()
     if u is None:
         self.u = Vector(x=1, y=0)
     else:
         self.u = u.copy()
Beispiel #3
0
def test_orientations():
    # left to right, arc above segment
    arc = Arc(Point(10, 20), Point(50, 30), Vector(10, 20))
    assert arc.ccw is False
    line = Line(Point(30, 10), Vector(10, 30))
    intersections = arc.intersection(line, sign_of_s=1)
    assert len(intersections) == 1

    # right to left, arc above segment
    arc = Arc(Point(50, 30), Point(10, 20), Vector(-10, 20))
    assert arc.ccw is True
    line = Line(Point(30, 10), Vector(10, 30))
    intersections = arc.intersection(line, sign_of_s=1)
    assert len(intersections) == 1

    # left to right, arc below segment
    arc = Arc(Point(10, 20), Point(50, 30), Vector(10, -20))
    assert arc.ccw is True
    line = Line(Point(30, 10), Vector(10, -30))
    intersections = arc.intersection(line, sign_of_s=1)
    assert len(intersections) == 1

    # right to left, arc below segment
    arc = Arc(Point(50, 30), Point(10, 20), Vector(-10, -20))
    assert arc.ccw is False
    line = Line(Point(30, 20), Vector(10, -30))
    intersections = arc.intersection(line, sign_of_s=1)
    assert len(intersections) == 1
Beispiel #4
0
    def interpolate(line_start, line_end, x):
        """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.
		
		Args:
			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:
			Line: Interpolated line.
		
		"""

        p = (1 - x) * line_start.p + x * line_end.p
        angle_start = line_start.u.theta_x()
        angle_end = line_end.u.theta_x()
        if angle_end < angle_start:
            # we want to go ccw from start to end
            angle_end += 2 * pi
        angle = (1 - x) * angle_start + x * angle_end
        u = Vector(x=cos(angle), y=sin(angle))
        return Line(p=p, u=u)
Beispiel #5
0
    def from_config(cls, config, scene=None, tag=None):
        """Alternate constructor.
		
		Args:
			config (dict): Configuration dictionary
		
		Returns:
			:class:`.Polycurve`: new Polycurve instance
		
		"""

        if tag is None:
            tag = config.get('tag')
        region = cls(scene=scene, tag=tag)
        curves_config = config['curves']
        M_start = Point.from_config(curves_config[0]['M1'])
        region.start(M_start)
        region.tag = config.get('tag')
        region.n = config['n']
        for curve_config in curves_config:
            cls = curve_config['Class']
            if cls == 'Segment':
                M_next = Point.from_config(curve_config['M2'])
                region.add_line(M_next)
            elif cls == 'Arc':
                M_next = Point.from_config(curve_config['M2'])
                tangent = Vector.from_config(curve_config['tangent'])
                region.add_arc(M_next, tangent)
            else:
                raise (NotImplementedError)
        # normally, the stored polycurves are already closed
        # (the last point is equal to the first one)
        # no need for a final close()
        return region
Beispiel #6
0
def test_create_line_handle(scene, parent_item):
    p = Point(10, 20)
    u = Vector(30, 60)
    line0 = Line(p, u)
    # The initial position should be free, even with move restrictions on
    scene.g.move_restrictions_on = True
    lh = LineHandle(line0, parent=parent_item)
    assert lh.h_p0.pos().x() == 10
    assert lh.h_p0.pos().y() == 20
Beispiel #7
0
def scene_polycurve_beam_singleray(scene):
    """Return a Scene with Polycurve region + Beam and SingleRay sources."""
    from geoptics.elements.vector import Point, Vector

    n = 1.5
    m1 = Point(70, 60)

    # rp1
    cls = scene.class_map['Regions']['Polycurve']
    rp1 = cls(n=n, scene=scene)
    rp1.start(m1)
    m2 = Point(70, 190)
    rp1.add_line(m2)
    m3 = Point(110, 190)
    rp1.add_line(m3)
    m4 = Point(110, 60)
    tg4 = Vector(10, -20)
    #rp1.add_line(m4)
    rp1.add_arc(m4, tg4)
    rp1.close()

    return scene
Beispiel #8
0
    def from_config(cls, config):
        """Alternate constructor.
		
		Args:
			config (dict): Configuration dictionary
		
		Returns:
			Line: new Line instance
		
		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
		
		"""
        p = Point.from_config(config['p'])
        u = Vector.from_config(config['u'])
        return cls(p, u)
Beispiel #9
0
def line():
    """Return a generic Line."""
    p = Point(10, 20)
    u = Vector(30, 60)
    return Line(p, u)
Beispiel #10
0
    scene = gui.scene

    # refractive index for rp1
    n = 1.5

    # rp1
    rp1 = geoptics.guis.qt.regions.Polycurve(n=n, scene=scene)
    m1 = Point(70, 60)
    rp1.start(m1)
    m2 = Point(70, 190)
    rp1.add_line(m2)
    m3 = Point(110, 190)
    rp1.add_line(m3)
    m4 = Point(110, 60)
    tg4 = Vector(10, -20)
    rp1.add_arc(m4, tg4)
    rp1.close()

    # tracé d'un rayon
    p0 = Point(10, 50)
    u0 = Vector(108, 0)
    s0 = 3
    n0 = 1.0

    p1 = Point(10, 80)
    u1 = Vector(108, 0)
    source2 = QtBeamOPL(line_start=Line(p0, u0),
                        line_end=Line(p1, u1),
                        s_start=100,
                        s_end=100,
Beispiel #11
0
def vector():
    """Return a generic Vector."""
    return Vector(30, 60)
Beispiel #12
0
class Line(object):
    """Line defined by a point `p` and a direction vector `u`.
	
	Args:
		p (Point): Reference point belonging to the line
		u (Vector): Direction vector
	
	"""
    def __init__(self, p=None, u=None):
        if p is None:
            self.p = Point(x=0, y=0)
        else:
            self.p = p.copy()
        if u is None:
            self.u = Vector(x=1, y=0)
        else:
            self.u = u.copy()

    @property
    def config(self):  # noqa: D401
        """Configuration dictionary."""
        return {
            'p': self.p.config,
            'u': self.u.config,
        }

    def copy(self):
        """Return an independent copy."""
        return Line(self.p, self.u)

    @classmethod
    def from_config(cls, config):
        """Alternate constructor.
		
		Args:
			config (dict): Configuration dictionary
		
		Returns:
			Line: new Line instance
		
		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
		
		"""
        p = Point.from_config(config['p'])
        u = Vector.from_config(config['u'])
        return cls(p, u)

    def normal(self, normalized=False):
        """Return a vector orthogonal to the line.
		
		Args:
			normalized (bool): if True, return a unit vector.
		
		Returns:
			:class:`.Vector`
		
		"""
        normal = self.u.normal(normalized)
        return normal

    def tangent(self, normalized=False):
        """Return a tangent vector to the line.
		
		For a line, this is basically `u` itself.
		
		Args:
			normalized (bool): if True, return a unit vector.
		
		Returns:
			:class:`.Vector`
		
		"""
        if normalized:
            tangent = self.u.copy()
            tangent.normalize()
            return tangent
        else:
            return self.u.copy()

    def intersection(self, other, sign_of_s=0):
        """Intersections of the line with another line.
		
		Args:
			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:
			:obj:`list` of :class:`Intersection`:
				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.
		
		"""
        if isinstance(other, Line):
            if other.u.colinear(self.u):
                result = []
            else:
                s = (((self.p.x - other.p.x) * self.u.y -
                      (self.p.y - other.p.y) * self.u.x) /
                     (other.u.x * self.u.y - other.u.y * self.u.x))
                if (sign_of_s == 0 and s != 0) or (s * sign_of_s > 0):
                    Mi = Point(other.p.x + s * other.u.x,
                               other.p.y + s * other.u.y)
                    eN = self.normal(normalized=True)
                    eT = self.tangent(normalized=True)
                    result = [Intersection(Mi, s, eN, eT)]
                else:
                    result = []
        else:
            raise NotImplementedError(
                "intersection between Line and {}".format(type(other)))
        return result

    @staticmethod
    def interpolate(line_start, line_end, x):
        """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.
		
		Args:
			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:
			Line: Interpolated line.
		
		"""

        p = (1 - x) * line_start.p + x * line_end.p
        angle_start = line_start.u.theta_x()
        angle_end = line_end.u.theta_x()
        if angle_end < angle_start:
            # we want to go ccw from start to end
            angle_end += 2 * pi
        angle = (1 - x) * angle_start + x * angle_end
        u = Vector(x=cos(angle), y=sin(angle))
        return Line(p=p, u=u)

    def point(self, s):
        """Return the :class:`.Point` at the position ``p + s * u``."""
        return Point(self.p.x + s * self.u.x, self.p.y + s * self.u.y)

    def __repr__(self):
        return "Line({p}, {u})".format(**vars(self))

    def translate(self, **kwargs):
        """Translate the starting point.
		
		Same syntax and same side effects as
		:py:func:`geoptics.elements.vector.Point.translate`
		
		Likewise, it is possible to insert a ``.copy()``
		to avoid side-effects.
		
		return `self` for convenience
		"""
        self.p.translate(**kwargs)
        return self
Beispiel #13
0
    scene = gui.scene

    # refractive index for rp1
    n = 1.5

    # rp1
    rp1 = regions.Polycurve(n=n, scene=scene)
    m1 = Point(70, 60)
    rp1.start(m1)
    m2 = Point(70, 190)
    rp1.add_line(m2)
    m3 = Point(110, 190)
    rp1.add_line(m3)
    m4 = Point(110, 60)
    tg4 = Vector(10, -20)
    #rp1.add_line(m4)
    rp1.add_arc(m4, tg4)
    rp1.close()

    #rp1.translate(Vector(0, 100))

    #rp2 = regions.Polycurve(n, scene=scene)
    #rp2.start(Point(121.0, 38.0))
    #rp2.add_line(Point(121.0, 168.0))
    #rp2.add_line(Point(161.0, 168.0))
    #rp2.add_line(Point(161.0, 38.0))
    #rp2.close()

    # tracé d'un rayon
    p0 = Point(10, 20)
Beispiel #14
0
def arc():
    """Return a generic Arc."""
    M1 = Point(10, 20)
    M2 = Point(50, 30)
    tangent = Vector(10, 20)
    return Arc(M1, M2, tangent)