def test_init_with_override(self):
     line = geom.Line(geom.STVector(0, 1, precision=7),
                      geom.STVector(2, 3, precision=7),
                      precision=5,
                      tag='test')
     self.assertEqual(line.precision(), 5)
     self.assertEqual(line.tag, 'test')
 def test_copy_ctor(self):
     stvec = geom.STVector(2,
                           3,
                           tag='test',
                           precision=4,
                           draw_options={'color': 'red'})
     stvec_cpy = geom.STVector(stvec)
     self.assertEqual(stvec.t, stvec_cpy.t)
     self.assertEqual(stvec.x, stvec_cpy.x)
     self.assertEqual(stvec.tag, 'test')
     self.assertEqual(stvec.precision, stvec_cpy.precision)
     self.assertEqual(stvec.draw_options, {'color': 'red'})
 def test_draw_in_bounds(self):
     p = _MockSTPlotter()
     geom.STVector(3, 4, tag='test', draw_options={'color': 'red'}).draw(p)
     self.assertEqual(len(p.points), 1)
     self.assertEqual(len(p.segments), 0)
     self.assertEqual(len(p.polygons), 0)
     self.assertEqual(p.points[0], ((3, 4), 'test', {'color': 'red'}))
     self.assertEqual(p.tlim, (3, 3))
     self.assertEqual(p.xlim, (4, 4))
 def test_in_bounds_exact_equality(self):
     self.assertTrue(geom.STVector(2, 3)._in_bounds((2, 2), (3, 3)))
 def setUp(self):
     self.original = geom.STVector(2, 3)
     self.transformed = geom.lorentz_transformed(self.original, 3 / 5)
Beispiel #6
0
#!/usr/bin/env python3
import sys
sys.path.append('..')

import specrel.geom as geom
import specrel.visualize as vis

# Set up "simultaneous events"
xvals = [-0.5, 0, 0.5]
colors = ['red', 'green', 'blue']
points = geom.PointGroup([
    geom.STVector(0, x, draw_options={'color': c})
    for x, c in zip(xvals, colors)
])

# Compare spacetime diagrams in different frames
v = 4 / 5  # Relative velocity between frames
tlim = (-0.75, 0.75)
xlim = (-1, 1)
markersize = 20
title = '"Simultaneous" events in different frames'
plotters = vis.compare_frames(points,
                              v,
                              tlim=tlim,
                              xlim=xlim,
                              title=title,
                              markersize=markersize)
p = plotters[0]
p.save('4-simultaneity.png')
p.show()
 def test_str(self):
     self.assertEqual(str(geom.STVector(2, 3)), 'STVector(2, 3)')
 def test_eq(self):
     self.assertEqual(geom.STVector(2, 3), (2, 3))
import sys
sys.path.append('..')

import specrel.geom as geom
import specrel.spacetime.physical as phy
import specrel.visualize as vis

# Plot a spacetime grid
tlim = (-5, 5)
xlim = (-5, 5)
stgrid = phy.stgrid(tlim, xlim)
plotter = vis.stplot(
    stgrid,
    title=
    'Spacetime diagram\n(Also known as "Minkowski" or "Worldline" diagram)',
    lim_padding=0)
plotter.save('1-spacetime_grid.png')
plotter.show()

# Plot a spacetime event
tlim = (0, 2)
xlim = (-2, 2)
event = geom.STVector(1, 1, draw_options={'label': 'Event'})
p = vis.stplot(event,
               title='An event in spacetime',
               tlim=tlim,
               xlim=xlim,
               grid=True,
               legend=True)
p.save('1-spacetime_event.png')
p.show()
 def test_lorentz_transform_origin_1_1(self):
     stvec = geom.STVector(3, 4)
     stvec.lorentz_transform(3 / 5, origin=(1, 1))
     self.assertAlmostEqual(stvec.t, 1 / 4 + 1)
     self.assertAlmostEqual(stvec.x, 9 / 4 + 1)
 def test_init_from_timepos(self):
     stvec = geom.STVector(2, 3)
     self.assertEqual(stvec.t, 2)
     self.assertEqual(stvec.x, 3)
 def test_abs(self):
     self.assertEqual(abs(geom.STVector(2, 3)), 5)
 def test_lorentz_transform(self):
     stvec = geom.STVector(2, 3)
     stvec.lorentz_transform(3 / 5)
     self.assertAlmostEqual(stvec.t, 1 / 4)
     self.assertAlmostEqual(stvec.x, 9 / 4)
 def test_add(self):
     self.assertEqual(geom.STVector(2, 3) + geom.STVector(3, 3), (5, 6))
 def test_neg(self):
     self.assertEqual(-geom.STVector(2, 3), geom.STVector(-2, -3))
 def test_eq_within_precision(self):
     self.assertEqual(geom.STVector(2, 3, precision=3), (2.0001, 3))
     self.assertNotEqual(geom.STVector(2, 3, precision=3), (2.001, 3))
 def test_append(self):
     self.collection.append(geom.STVector(5, 5))
     self.assertEqual(len(self.collection), 4)
     self.assertEqual(self.collection[3], (5, 5))
 def test_init_from_iterable(self):
     stvec = geom.STVector((2, 3))
     self.assertEqual(stvec.t, 2)
     self.assertEqual(stvec.x, 3)
 def test_str_within_precision(self):
     self.assertEqual(str(geom.STVector(2.001, 2.999, precision=3)),
                      'STVector(2.001, 2.999)')
     self.assertEqual(str(geom.STVector(2.0001, 2.9999, precision=3)),
                      'STVector(2.0, 3.0)')
 def test_copy_ctor_with_override(self):
     stvec = geom.STVector(2, 3, precision=4)
     stvec_cpy = geom.STVector(stvec, precision=6, tag='test')
     self.assertEqual(stvec_cpy.precision, 6)
     self.assertEqual(stvec_cpy.tag, 'test')
 def test_cannot_append(self):
     self.assertRaises(TypeError,
                       geom.Line((0, 1), (2, 3)).append,
                       geom.STVector(1, 1))
 def test_iter(self):
     for cmp, answer in zip(geom.STVector(2, 3), [2, 3]):
         self.assertEqual(cmp, answer)
 def test_draw_out_of_bounds(self):
     p = _MockSTPlotter()
     geom.STVector(3, 4).draw(p, tlim=(4, 5))
     self.assertEqual(len(p.points), 0)
     self.assertEqual(len(p.segments), 0)
     self.assertEqual(len(p.polygons), 0)
 def test_auto_draw_lims(self):
     self.assertEqual(
         geom.STVector(2, 3)._auto_draw_lims(), ((2, 2), (3, 3)))
 def test_getitem(self):
     stvec = geom.STVector(2, 3)
     self.assertEqual(stvec[0], 2)
     self.assertEqual(stvec[1], 3)
 def test_in_bounds(self):
     stvec = geom.STVector(2, 3)
     self.assertTrue(stvec._in_bounds((0, 3), (2, 4)))
     self.assertFalse(stvec._in_bounds((3, 4), (1, 2)))
    draw_options=closed_draw_options)

# Exact event of closing/opening each door
close_event_draw_options = {
    'color': 'red',
    'marker': 'v',
    'markersize': 10,
    'label': 'Close door',
}
open_event_draw_options = {
    'color': 'limegreen',
    'marker': '^',
    'markersize': 10,
    'label': 'Open door',
}
left_close_event = geom.STVector(t_transition, garage.left_pos(t_transition),
    draw_options=close_event_draw_options)
right_open_event = geom.STVector(t_transition, garage.right_pos(t_transition),
    draw_options=open_event_draw_options)

# Synthesize the scene
scene = geom.Collection([
    garage, ladder,
    left_closed, right_closed,
    left_close_event, right_open_event,
])

tlim = (t_start, t_end)
xlim = (ladder_left_start - ladder_length, ladder.right_pos(t_end))

# Plot the frames
legend = True
    def test_in_bounds_within_precision(self):
        stvec1 = geom.STVector(2.0001, 3.0001, precision=3)
        self.assertTrue(stvec1._in_bounds((0, 2), (2, 3)))

        stvec2 = geom.STVector(2.001, 3.001, precision=3)
        self.assertFalse(stvec2._in_bounds((0, 2), (2, 3)))
t_return = rocket_backward_alltime.time_for_left_pos(origin)
rocket_backward = geom.line_segment((t_turnaround, x_planet), (t_return, 0),
    draw_options={
        'color': 'darkorange',
        'marker': '<',
        'markersize': 5,
        'linestyle': ':',
        'label': 'Traveler (backward)',
    }
)

# Mark events
turnaround_event = geom.STVector(t_turnaround, x_planet,
    draw_options={
        'color': 'green',
        'marker': '*',
        'markersize': 10,
        'label': 'Turning around',
    }
)
return_event = geom.STVector(t_return, origin,
    draw_options={
        'color': 'red',
        'marker': '*',
        'markersize': 10,
        'label': 'Arrive home',
    }
)

# Collect scene
scene = geom.Collection([
    earth, planet,
Beispiel #30
0
def gradient_line(point1,
                  point2,
                  color1,
                  color2,
                  divisions=100,
                  extrapolate_color=True,
                  draw_options=geom.geomrc['draw_options']):
    """A line with a color gradient. The gradient transition will happen over
    a finite range in spacetime, and be monochromatic at either end.

    Args:
        point1 (specrel.geom.STVector or iterable): Starting point of the
            gradient.
        point2 (specrel.geom.STVector or iterable): Ending point of the
            gradient.
        color1 (color): A Matplotlib color for the gradient starting color.
        color2 (color): A Matplotlib color for the gradient ending color.
        divisions (int, optional): The number of line segment divisions in the
            gradient. More divisions means a smoother gradient.
        extrapolate_color (bool, optional): Flag for whether or not to
            extrapolate the color gradient across the line past the specified
            endpoints so that the color change spans as far as possible across
            the line.
        draw_options (dict, optional): See `specrel.geom.LorentzTransformable`.

    Returns:
        specrel.geom.Collection:
            Collection containing the color gradient increments, in the order:

            1. `specrel.geom.Ray` before `point1` with `color1`.
            2. Line segments changing color from `point1` to `point2`.
            3. `specrel.geom.Ray` after `point2` with `color2`.
    """
    # Copy draw_options and remove color if it's there
    draw_options = dict(draw_options)
    draw_options.pop('color', None)

    # If extrapolating color, calculate the color gradient extremes
    if extrapolate_color:
        point1, point2, color1, color2, divisions = _colorgrad_extremes(
            point1, point2, color1, color2, divisions)

    # Color gradient calculator for the given points and colors
    def this_colorgrad(x):
        return _calc_colorgrad(x, point1, point2, color1, color2)

    # Line direction vector
    direc = geom.STVector(point2) - geom.STVector(point1)

    grad = geom.Collection()
    # Monochromatic ray at the tail end of the gradient line
    grad.append(
        geom.Ray(-direc,
                 point1,
                 draw_options={
                     'color': color1,
                     **draw_options
                 }))
    # The line segments comprising the color gradient
    for i in range(divisions):
        start_point, _ = this_colorgrad(i / divisions)
        end_point, _ = this_colorgrad((i + 1) / divisions)
        _, grad_color = this_colorgrad((i + 1 / 2) / divisions)
        grad.append(
            geom.line_segment(start_point,
                              end_point,
                              draw_options={
                                  'color': grad_color,
                                  **draw_options
                              }))
    # Monochromatic ray at the head end of the gradient line
    grad.append(
        geom.Ray(direc, point2, draw_options={
            'color': color2,
            **draw_options
        }))
    return grad