コード例 #1
0
 def test_draw_totally_out_of_bounds(self):
     p = _MockSTPlotter()
     h = geom.HalfRibbon(geom.Ray((0, 1), (2, 3)), geom.Ray((0, 1), (0, 2)))
     h.draw(p, tlim=(-2, 3), xlim=(0, 1))
     self.assertEqual(len(p.points), 0)
     self.assertEqual(len(p.segments), 0)
     self.assertEqual(len(p.polygons), 0)
コード例 #2
0
 def test_draw_endpoints_one_endpoint_out_of_bounds(self):
     p = _MockSTPlotter()
     h = geom.HalfRibbon(geom.Ray((0, 1), (2, 0.5)),
                         geom.Ray((0, 1), (0, -0.5)),
                         draw_options={'edgecolor': 'None'})
     h.draw(p, tlim=(-2, 3), xlim=(0, 1))
     self.assertEqual(len(p.points), 0)
     self.assertEqual(len(p.segments), 0)
     self.assertEqual(len(p.polygons), 1)
     p.polygons_equal(self, p.polygons[0], ([(0, 0), (0, 1), (2, 1),
                                             (2, 0.5), (1, 0)], None, {}))
コード例 #3
0
 def test_draw_totally_out_of_bounds(self):
     ray = geom.Ray((1, 1), (2, 3))
     p = _MockSTPlotter()
     ray.draw(p, tlim=(-1, 2), xlim=(0, 2))
     self.assertEqual(len(p.points), 0)
     self.assertEqual(len(p.segments), 0)
     self.assertEqual(len(p.polygons), 0)
コード例 #4
0
 def test_boundary_intersections_exterior_endpoint(self):
     ray = geom.Ray((0, 1), (0.5, -1))
     tlim = (0, 1)
     xlim = (0, 1)
     self.assertEqual(ray._boundary_intersections(tlim, xlim), [(0.5, -1),
                                                                (0.5, 0),
                                                                (0.5, 1)])
コード例 #5
0
 def test_intersect_equal_lines_diff_direction_diff_point(self):
     ray = geom.Ray((1, 1), (2, 3))
     line = geom.Line((2, 2), (3, 4))
     intersection = ray.intersect(line)
     self.assertIsInstance(intersection, geom.Ray)
     self.assertEqual(intersection.direction(), ray.direction())
     self.assertEqual(intersection.point(), ray.point())
コード例 #6
0
 def test_draw_endpoint_in_bounds(self):
     ray = geom.Ray((1, 1), (0, 1))
     p = _MockSTPlotter()
     ray.draw(p, tlim=(-1, 2), xlim=(0, 2))
     self.assertEqual(len(p.points), 0)
     self.assertEqual(len(p.segments), 1)
     self.assertEqual(len(p.polygons), 0)
     p.segments_equal(self, p.segments[0], ((0, 1), (1, 2), None, {}))
コード例 #7
0
 def test_extrapolate_color(self):
     gradln = grad.gradient_line((1/3, 1/3), (2/3, 2/3),
         (2/3, 0, 1/3, 1), (1/3, 0, 2/3, 1), divisions=1)
     self.assertEqual(len(gradln), 5)
     self.assertEqual(gradln[0], geom.Ray((-1, -1), (0, 0)))
     _tuple_eq(self, gradln[0].draw_options['color'], (1, 0, 0, 1))
     self.assertEqual(gradln[1][0], (0, 0))
     self.assertEqual(gradln[1][1], (1/3, 1/3))
     _tuple_eq(self, gradln[1].draw_options['color'], (5/6, 0, 1/6, 1))
     self.assertEqual(gradln[2][0], (1/3, 1/3))
     self.assertEqual(gradln[2][1], (2/3, 2/3))
     _tuple_eq(self, gradln[2].draw_options['color'], (3/6, 0, 3/6, 1))
     self.assertEqual(gradln[3][0], (2/3, 2/3))
     self.assertEqual(gradln[3][1], (1, 1))
     _tuple_eq(self, gradln[3].draw_options['color'], (1/6, 0, 5/6, 1))
     self.assertEqual(gradln[4], geom.Ray((1, 1), (1, 1)))
     _tuple_eq(self, gradln[4].draw_options['color'], (0, 0, 1, 1))
コード例 #8
0
 def test_longitudinal_gradient_ribbon(self):
     gradribbon = grad.longitudinal_gradient_ribbon(
         ((0, 0), (1, 0)), ((0, 1), (1, 1)),
         (1, 0, 0, 1), (0, 0, 1, 1), divisions=1)
     self.assertEqual(len(gradribbon), 3)
     self.assertEqual(gradribbon[0][0], geom.Ray((-1, 0), (0.5, 0)))
     self.assertEqual(gradribbon[0][1], geom.Ray((-1, 0), (0.5, 1)))
     _tuple_eq(self, gradribbon[0].draw_options['facecolor'], (1, 0, 0, 1))
     self.assertEqual(gradribbon[1][0], (0, 0))
     self.assertEqual(gradribbon[1][1], (1.5, 0))
     self.assertEqual(gradribbon[1][2], (1.5, 1))
     self.assertEqual(gradribbon[1][3], (0, 1))
     _tuple_eq(self, gradribbon[1].draw_options['facecolor'],
         (1/2, 0, 1/2, 1))
     self.assertEqual(gradribbon[2][0], geom.Ray((1, 0), (1, 0)))
     self.assertEqual(gradribbon[2][1], geom.Ray((1, 0), (1, 1)))
     _tuple_eq(self, gradribbon[2].draw_options['facecolor'], (0, 0, 1, 1))
コード例 #9
0
 def test_auto_draw_lims(self):
     ray = geom.Ray((1, -1), (2, 3))
     self.assertEqual(ray._auto_draw_lims(), ((2, 3), (2, 3)))
コード例 #10
0
 def test_init_error_on_antiparallel(self):
     self.assertRaises(ValueError, geom.HalfRibbon, geom.Ray((0, 1),
                                                             (0, 0)),
                       geom.Ray((0, -1), (2, 3)))
コード例 #11
0
 def test_ghost_intersection(self):
     ray = geom.Ray((1, 0), (2, 1))
     line = geom.Line((0, 1), (1, 0))
     self.assertIsNone(ray.intersect(line))
コード例 #12
0
 def test_actual_intersection_tangent(self):
     ray = geom.Ray((1, 0), (1, 1))
     line = geom.Line((0, 1), (1, 0))
     self.assertEqual(ray.intersect(line), (1, 1))
コード例 #13
0
 def test_actual_intersection_full_crossing(self):
     ray = geom.Ray((1, 0), (0, 1))
     line = geom.Line((0, 1), (1, 0))
     self.assertEqual(ray.intersect(line), (1, 1))
コード例 #14
0
 def test_str(self):
     self.assertEqual(str(geom.Ray((0, 1), (2, 3))),
                      'Ray( [t, x] = [2, 3] + k*[0, 1] where k >= 0 )')
コード例 #15
0
 def test_intersect_parallel(self):
     ray = geom.Ray((1, 1), (0, 0))
     line = geom.Line((2, 2), (0, 1))
     self.assertIsNone(ray.intersect(line))
コード例 #16
0
 def test_eq(self):
     self.assertEqual(geom.Ray((1, 1), (2, 3)), geom.Ray((1, 1), (2, 3)))
コード例 #17
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
コード例 #18
0
ファイル: 7-ftl.py プロジェクト: johanngan/special_relativity
v_away = 1/2
v_message = 4
t_send = 1
person1 = phy.MovingObject(0, velocity=-v_away,
    draw_options={'color': 'red', 'label': 'Person 1', 'markersize': 15})
person2 = phy.MovingObject(0, velocity=v_away,
    draw_options={'color': 'blue', 'label': 'Person 2', 'markersize': 15})
# Extensions of the messages to all time, even though they don't exist for all
# time. The lines are useful for intersection calculations
joke_alltime = phy.MovingObject(person2.center_pos(t_send), start_time=t_send,
    velocity=-v_message)
# Get the left edge of the MovingObject; since it's a point object it's just
# the worldline
joke_sent = joke_alltime.left().intersect(person1.left())
# The actual joke object to draw
joke = geom.Ray((-1, v_message), joke_sent, tag='*Joke*',
    draw_options={'color': 'red', 'linestyle': '--', 'marker': '>'})
# Mark the point of receipt
joke_received = joke.intersect(person2.left())
joke_received.draw_options = {
    'color': 'limegreen',
    'marker': '*',
    'markersize': 10,
    'label': 'Joke received'
}
# Repeat for the response stuff
response_alltime = phy.MovingObject(person1.center_pos(t_send),
    start_time=t_send, velocity=v_message, tag='Hahaha!',
    draw_options={'color': 'blue', 'linestyle': '--', 'marker': '<'})
response_sent = response_alltime.left().intersect(person2.left())
response = geom.Ray((-1, -v_message), response_sent, tag='Hahaha!',
    draw_options={'color': 'blue', 'linestyle': '--', 'marker': '<'})
コード例 #19
0
 def test_neq_opp_dir(self):
     self.assertNotEqual(geom.Ray((1, 1), (2, 3)), geom.Ray((-1, -1),
                                                            (2, 3)))
コード例 #20
0
 def test_neq_diff_point(self):
     self.assertNotEqual(geom.Ray((1, 1), (2, 3)), geom.Ray((1, 1), (1, 2)))
コード例 #21
0
 def test_eq_scaled_dir(self):
     self.assertEqual(geom.Ray((1, 1), (2, 3)), geom.Ray((2, 2), (2, 3)))
コード例 #22
0
)
# Add a few more frills to the drawing
door_draw_options = {'linestyle': '--', 'marker': '|', 'markersize': 10}
garage[0].draw_options = door_draw_options
garage[1].draw_options = door_draw_options

# Time range
t_start = 0
# End when the ladder totally clears the garage
t_end = ladder.time_for_left_pos(garage.right_pos(0))
# Time when the garage doors are opened/closd
t_transition = ladder.time_for_left_pos(garage.left_pos(0))

# Whole period when each door is closed
closed_draw_options = {'color': 'red', 'marker': '|', 'markersize': 10}
left_closed = geom.Ray((1, 0), (t_transition, garage.left_pos(0)),
    draw_options=closed_draw_options)
right_closed = geom.Ray((-1, 0), (t_transition, garage.right_pos(0)),
    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',
コード例 #23
0
def longitudinal_gradient_ribbon(line1_endpoints,
                                 line2_endpoints,
                                 color1,
                                 color2,
                                 divisions=100,
                                 extrapolate_color=True,
                                 draw_options=geom.geomrc['draw_options']):
    """A `specrel.geom.Ribbon`-esque object with a longitudinal color gradient
    (across the infinite direction).

    Args:
        line1_endpoints (list): list of two `specrel.geom.STVector`-convertible
            points defining the start and end positions of the gradient along
            the first edge of the ribbon.
        line2_endpoints (list): Same as `line1_endpoints`, but for the second
            edge of the ribbon.
        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 ribbon past the specified
            endpoints so that the color change spans as far as possible across
            the ribbon.
        draw_options (TYPE, optional): See `specrel.geom.LorentzTransformable`.

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

            1. `specrel.geom.HalfRibbon` with `color1` before both line starting
                points.
            2. Polygons changing color from starts of the lines to the ends.
            3. `specrel.geom.HalfRibbon` with `color2` after both line ending
                points.
    """
    # Copy draw_options and remove color, facecolor, and edgecolor if they're
    # there
    draw_options = dict(draw_options)
    draw_options.pop('color', None)
    draw_options.pop('facecolor', None)
    draw_options.pop('edgecolor', None)

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

    # Color gradient calculators for each line with the given colors
    def line1_colorgrad(x):
        return _calc_colorgrad(x, *line1_endpoints, color1, color2)

    def line2_colorgrad(x):
        return _calc_colorgrad(x, *line2_endpoints, color1, color2)

    # Direction vectors of each line
    direc1 = geom.STVector(line1_endpoints[1]) - geom.STVector(
        line1_endpoints[0])
    direc2 = geom.STVector(line2_endpoints[1]) - geom.STVector(
        line2_endpoints[0])
    grad = geom.Collection()
    # Form the monochromatic half ribbon at the tail end of the gradient
    # Overlap with the first polygon by half a division to mitigate any
    # boundary gaps
    start_point1, _ = line1_colorgrad(1 / (2 * divisions))
    start_point2, _ = line2_colorgrad(1 / (2 * divisions))
    grad.append(
        geom.HalfRibbon(
            geom.Ray(-direc1, start_point1),
            geom.Ray(-direc2, start_point2),
            # Explicitly turn off edge coloring
            draw_options={
                'facecolor': color1,
                'edgecolor': 'None',
                **draw_options
            }))
    # Interior polygons comprising the color gradient
    for i in range(divisions):
        start_point1, _ = line1_colorgrad(i / divisions)
        # Overlap bands by half a division
        end_point1, _ = line1_colorgrad((i + 1 + 1 / 2) / divisions)
        start_point2, _ = line2_colorgrad(i / divisions)
        end_point2, _ = line2_colorgrad((i + 1 + 1 / 2) / divisions)
        _, grad_color = line1_colorgrad((i + 1 / 2) / divisions)
        grad.append(
            geom.polygon([start_point1, end_point1, end_point2, start_point2],
                         draw_options={
                             'facecolor': grad_color,
                             **draw_options
                         }))
    # Monochromatic half ribon at the head end of the gradient
    grad.append(
        geom.HalfRibbon(geom.Ray(direc1, line1_endpoints[1]),
                        geom.Ray(direc2, line2_endpoints[1]),
                        draw_options={
                            'facecolor': color2,
                            'edgecolor': 'None',
                            **draw_options
                        }))
    return grad