File:Transmission line animation3.gif

Transmission_line_animation3.gif(300 × 60 pixels, file size: 138 KB, MIME type: image/gif, looped, 100 frames, 5.0 s)

Summary

Description
English: A wave traveling rightward along a lossless transmission line. Black dots represent electrons, and arrows show the electric field.
Date
Source Own work
Author Sbyrnes321

Licensing

I, the copyright holder of this work, hereby publish it under the following license:
Creative Commons CC-Zero This file is made available under the Creative Commons CC0 1.0 Universal Public Domain Dedication.
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of their rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.

Source code

""" (C) Steven Byrnes, 2014-2016. This code is released under the MIT license http://opensource.org/licenses/MIT  This code runs in Python 2.7 or 3.3. It requires imagemagick to be installed; that's how it assembles images into animated GIFs. """  from __future__ import division  import pygame as pg from numpy import cos, pi, sin, linspace  import subprocess, os directory_now = os.path.dirname(os.path.realpath(__file__))  frames_in_anim = 100 animation_loop_seconds = 5 #time in seconds for animation to loop one cycle  bgcolor = (255,255,255) #background is white ecolor = (0,0,0) #electrons are black wire_color = (200,200,200) # wire color is light gray arrow_color = (140,0,0)  # pygame draws pixel-art, not smoothed. Therefore I am drawing it # bigger, then smoothly shrinking it down img_height = 180 img_width = 900 final_height = 60 final_width = 300  # ~23 megapixel limit for wikipedia animated gifs assert final_height * final_width * frames_in_anim < 22e6  #transmission line thickness, and y-coordinate of the top of each wire tl_thickness = 27 tl_top_y = 40 tl_bot_y = img_height - tl_top_y - tl_thickness + 2  wavelength = 1.1 * img_width  e_radius = 4  # dimensions of triangular arrow head (this is for the longest arrows; it's # scaled down when the arrow is too small) arrowhead_base = 9 arrowhead_height = 15 # width of the arrow line arrow_width = 6  # number of electrons spread out over the transmission line (top plus bottom) num_electrons = 100 # max_e_displacement is defined here as a multiple of the total electron path length # (roughly twice the width of the image, because we're adding top + bottom) max_e_displacement = 1/60  num_arrows = 20 max_arrow_halflength = 22  def tup_round(tup):     """round each element of a tuple to nearest integer"""     return tuple(int(round(x)) for x in tup)  def draw_arrow(surf, x, tail_y, head_y):     """     draw a vertical arrow. Coordinates do not need to be integers     """     # calculate dimensions of the triangle; it's scaled down for short arrows     if abs(head_y - tail_y) >= 1.5 * arrowhead_height:         h = arrowhead_height         b = arrowhead_base     else:         h = abs(head_y - tail_y) / 1.5         b = arrowhead_base * h / arrowhead_height      if tail_y < head_y:         # downward arrow         triangle = [tup_round((x, head_y)),                     tup_round((x - b, head_y - h)),                     tup_round((x + b, head_y - h))]         triangle_middle_y = head_y - h/2     else:         # upward arrow         triangle = [tup_round((x, head_y)),                     tup_round((x - b, head_y + h)),                     tup_round((x + b, head_y + h))]         triangle_middle_y = head_y + h/2     pg.draw.line(surf, arrow_color, tup_round((x, tail_y)), tup_round((x, triangle_middle_y)), arrow_width)     pg.draw.polygon(surf, arrow_color, triangle, 0)  def e_path(param, phase_top_left):     """     as param goes 0 to 1, this returns {'pos': (x, y), 'phase':phi},     where (x,y) is the coordinates of the corresponding point on the electron     dot path, and phi is the phase for an electron at that point on the path.     phase_top_left is phase of the left side of the top wire.     """     # d is a vertical offset between the electrons and the wires     d = tl_thickness - e_radius - 2     # pad is how far to extend the transmission line beyond the image borders     # (since those electrons may enter the image a bit)     pad = 36     path_length = 2*(img_width + 2*pad)     howfar = param * path_length      # move right across top transmission line     if howfar <= path_length / 2:         x = howfar - pad         y = tl_top_y + d         phase = phase_top_left + 2 * pi * x / wavelength         return {'pos':(x,y), 'phase':phase}     # ...then move left across the bottom transmission line     x = path_length - howfar - pad     y = tl_bot_y + tl_thickness - d     phase = phase_top_left + 2 * pi * x / wavelength     return {'pos':(x,y), 'phase':phase}  def main():     #Make and save a drawing for each frame     filename_list = [os.path.join(directory_now, 'temp' + str(n) + '.png')                          for n in range(frames_in_anim)]      for frame in range(frames_in_anim):         phase_top_left = -2 * pi * frame / frames_in_anim          #initialize surface         surf = pg.Surface((img_width,img_height))         surf.fill(bgcolor);          #draw transmission line         pg.draw.rect(surf, wire_color, [0, tl_top_y, img_width, tl_thickness])         pg.draw.rect(surf, wire_color, [0, tl_bot_y, img_width, tl_thickness])          #draw electrons. Remember, "param" is an abstract coordinate that goes         #from 0 to 1 as the electron position goes right across the top wire         #then left across the bottom wire         equilibrium_params = linspace(0, 1, num=num_electrons)         phases = [e_path(a, phase_top_left)['phase'] for a in equilibrium_params]         now_params = [equilibrium_params[i] + sin(phases[i]) * max_e_displacement                            for i in range(num_electrons)]         coords = [e_path(a, phase_top_left)['pos'] for a in now_params]         for coord in coords:             pg.draw.circle(surf, ecolor, tup_round(coord), e_radius)          #draw arrows         arrow_params = linspace(0, 0.5, num=num_arrows)         for i in range(len(arrow_params)):             a = arrow_params[i]             arrow_x = e_path(a, phase_top_left)['pos'][0]             arrow_phase = e_path(a, phase_top_left)['phase']             head_y = img_height/2 + max_arrow_halflength * cos(arrow_phase)             tail_y = img_height/2 - max_arrow_halflength * cos(arrow_phase)             draw_arrow(surf, arrow_x, tail_y, head_y)          #shrink the surface to its final size, and save it         shrunk_surface = pg.transform.smoothscale(surf, (final_width, final_height))         pg.image.save(shrunk_surface, filename_list[frame])      seconds_per_frame = animation_loop_seconds / frames_in_anim     frame_delay = str(int(seconds_per_frame * 100))     # Use the "convert" command (part of ImageMagick) to build the animation     command_list = ['convert', '-delay', frame_delay, '-loop', '0'] + filename_list + ['anim.gif']     subprocess.call(command_list, cwd=directory_now)     # Earlier, we saved an image file for each frame of the animation. Now     # that the animation is assembled, we can (optionally) delete those files     if True:         for filename in filename_list:             os.remove(filename)  main() 

Captions

Add a one-line explanation of what this file represents

Items portrayed in this file

depicts

9 November 2014

File history

Click on a date/time to view the file as it appeared at that time.

Date/TimeThumbnailDimensionsUserComment
current01:53, 29 May 2016Thumbnail for version as of 01:53, 29 May 2016300 × 60 (138 KB)Sbyrnes321don't change the arrow color, for image simplicity
00:39, 10 November 2014Thumbnail for version as of 00:39, 10 November 2014300 × 60 (238 KB)Sbyrnes321User created page with UploadWizard

Global file usage

The following other wikis use this file: