def update(pad=None, tname=None, fixed=False, color=None): pobj = pdict[pad.name] if fixed: ccolor = vpython.color.orange else: ccolor = vpython.color.white if (color is not None): ccolor = color if (color != v(1.0, 1.0, 1.0)): # wmult = 3 # only useful for plots showing lightning wmult = 1 else: wmult = 1 else: wmult = 1 if (tname is not None) and (tname in pad.inputs): tpos = v(pad.inputs[tname][0].east, pad.inputs[tname][0].north, 0.0) cobj = vpython.arrow(pos=pobj.pos, axis=(tpos - pobj.pos), shaftwidth=ARROWWIDTH * wmult, fixedwidth=True, color=ccolor) pobj.cables[tname] = cobj else: for cable in pobj.cables.values(): cable.visible = False pobj.cables = {} for tname, tdata in pad.inputs.items(): tpos = v(tdata[0].east, tdata[0].north, 0.0) cobj = vpython.arrow(pos=pobj.pos, axis=(tpos - pobj.pos), shaftwidth=ARROWWIDTH * wmult, fixedwidth=True, color=ccolor) pobj.cables[tname] = cobj
def processClick(event): global seltile, tlabel, scene try: # Key pressed: s = event.key if s == 'c': for ob in simplist: ob.visible = False for ob in complist: ob.visible = True elif s == 's': for ob in complist: ob.visible = False for ob in simplist: ob.visible = True except AttributeError: # Mouse clicked: clickedpos = scene.mouse.project(normal=v( 0, 0, 1), d=0) # Mouse position projected onto XY plane if clickedpos: scene.center = clickedpos # Change the camera centre position ob = scene.mouse.pick try: name = ob.name if seltile is not None: seltile.color = color.green tlabel.visible = False del tlabel seltile = ob seltile.color = color.red tlabel = vpython.label(pos=v(seltile.pos.x, seltile.pos.y, seltile.pos.z + 10), text=name, height=15) except AttributeError: pass
def trunk(pad=None): pobj = pdict[pad.name] trcolor = v(0.0, 0.9, 0.9) trobj = vpython.arrow(pos=v(0, 0, 0), axis=pobj.pos, shaftwidth=ARROWWIDTH * 3, fixedwidth=True, color=trcolor) trobj.visible = True
def gettile(cpos=None): if cpos is None: cpos = v((0, 0, 0)) elif type(cpos) == tuple: cpos = v(cpos) dip_sep = 1.10 # dipole separations in meters xoffsets = [0.0] * 16 # offsets of the dipoles in the W-E 'x' direction yoffsets = [0.0] * 16 # offsets of the dipoles in the S-N 'y' direction xoffsets[0] = -1.5 * dip_sep xoffsets[1] = -0.5 * dip_sep xoffsets[2] = 0.5 * dip_sep xoffsets[3] = 1.5 * dip_sep xoffsets[4] = -1.5 * dip_sep xoffsets[5] = -0.5 * dip_sep xoffsets[6] = 0.5 * dip_sep xoffsets[7] = 1.5 * dip_sep xoffsets[8] = -1.5 * dip_sep xoffsets[9] = -0.5 * dip_sep xoffsets[10] = 0.5 * dip_sep xoffsets[11] = 1.5 * dip_sep xoffsets[12] = -1.5 * dip_sep xoffsets[13] = -0.5 * dip_sep xoffsets[14] = 0.5 * dip_sep xoffsets[15] = 1.5 * dip_sep yoffsets[0] = 1.5 * dip_sep yoffsets[1] = 1.5 * dip_sep yoffsets[2] = 1.5 * dip_sep yoffsets[3] = 1.5 * dip_sep yoffsets[4] = 0.5 * dip_sep yoffsets[5] = 0.5 * dip_sep yoffsets[6] = 0.5 * dip_sep yoffsets[7] = 0.5 * dip_sep yoffsets[8] = -0.5 * dip_sep yoffsets[9] = -0.5 * dip_sep yoffsets[10] = -0.5 * dip_sep yoffsets[11] = -0.5 * dip_sep yoffsets[12] = -1.5 * dip_sep yoffsets[13] = -1.5 * dip_sep yoffsets[14] = -1.5 * dip_sep yoffsets[15] = -1.5 * dip_sep gp = vpython.box(pos=v(0, 0, 0) + cpos, axis=v(0, 0, 1), height=5.0, width=5.0, length=0.05, color=color.gray(0.5), visible=False) olist = [gp] for i in range(16): dlist = getdipole(cpos=v(xoffsets[i], yoffsets[i], 0) + cpos) olist += dlist return olist
def mainloop(): global t, tlabel, lasttime, timingstring if int(startt - t) % PrInterval == 0: # Occasionally update timing information timingstring = "%4.3f seconds per %d days" % (time.time() - lasttime, PrInterval) lasttime = time.time() # print(timingstring) # Use the Nbody engine to run the model for 'Substeps' steps, each of time 'dt' nbody.Process(t, steps=Substeps, dt=dt) t = t + dt * Substeps tlabel.text = "Year=%6.4f (%d JD). Timing: %s" % ( (t - 2451545.0) / 365.246 + 2000.0, t, timingstring) # Update positions of display objects nbody.UpdatePositions(vclass=v) # Update display window viewing center and viewing angle if scenecenter != bodies['Sun']: scene.center = scenecenter.body.pos tlabel.pos = scene.center if Tracking: bvec = v(*nbody.hp[scenecenter.i]).norm() scene.camera.axis = (TrackAngle + bvec) * TrackMag scene.camera.pos = scenecenter.body.pos - scene.camera.axis
def geteda(offsets=EDAOFFSETS): """Create and return a list of 3D objects making up the entire 256 element Engineering Development Array, using the dipole locations in locations.txt """ gp = vpython.box(pos=v(0, 0, 0), axis=v(0, 0, 1), height=40.0, width=40.0, length=0.05, color=color.gray(0.5)) olist = [gp] for bfid in pointing.HEXD: for dipid in pointing.HEXD: dlist = getdipole(cpos=v(*offsets[bfid][dipid]), dlabel=bfid + dipid) olist += dlist eaxis = vpython.arrow(pos=v(0, 0, 0), axis=v(20, 0, 0), color=color.blue, shaftwidth=0.1, fixedwidth=True, opacity=0.2) naxis = vpython.arrow(pos=v(0, 0, 0), axis=v(0, 20, 0), color=color.blue, shaftwidth=0.1, fixedwidth=True, opacity=0.2) eaxislabel = vpython.text(text='E', pos=v(20, 0, 0.2), height=0.5, depth=0.1, color=color.blue, opacity=0.2) naxislabel = vpython.text(text='N', pos=v(0, 20, 0.2), height=0.5, depth=0.1, color=color.blue, opacity=0.2) olist += [eaxis, naxis, eaxislabel, naxislabel] return olist
def ShowErrors(): """For each of Sun, Mercury,...,Ceres, recalculate the position for the current time using the ephemeris library, and display an arrow indicating the difference between the current modelled position and the calculated ephemeris position. The errors will gradually increase, because of the non-real effects of any random asteroids, because many real bodies are not in the model (real asteroids/comets/moons, nearby stars, etc), and because the initial velocity calculation is fairly crude, much less accurate than the position. """ global arrows sunpos = copy(bodies['Sun'].body.pos) for ar in arrows: ar.visible = False arrows = [] for name in Planets: if name in bodies.keys(): bod = bodies[name] bod.calc(Teph=t) curpos = v(copy(bod.body.pos)) errvec = v(*bod.pos) + sunpos - curpos if bod.body: arrows.append( vpython.arrow(pos=curpos, axis=errvec, shaftwidth=0.5 * dispmult))
def setbody(self, color=None, dradius=None, rings=None, simple=False, up=None, texture=None): """Define the sphere representing the object itself. The radius is given in units of 'dispmult', a global parameter allowing human-friendly sizes. Store initial position, mass, and momentum from the ephemeris library. if simple is True, use a simple_sphere object with fewer vertices, to render faster. """ if color is None: color = self.color else: self.color = color if dradius is None: dradius = self.dradius else: self.dradius = dradius if texture is None: texture = self.texture else: self.texture = texture if rings is None: rings = self.rings else: self.rings = rings if up is None: up = self.up else: self.up = up if rings: # self.body = vpython.frame(pos=v(*self.pos)) rings = vpython.cylinder( pos=v(0, 0, 0), radius=dradius * dispmult * 3, axis=v(0, 1, 0), # (0, 1, 2) length=0.1 * dispmult, color=color, texture=texture, up=v(*up)) if simple: planet = vpython.simple_sphere(pos=v(0, 0, 0), radius=dradius * dispmult, color=color, up=v(*up)) else: planet = vpython.sphere(pos=v(0, 0, 0), radius=dradius * dispmult, color=color, texture=texture, up=v(*up)) self.body = vpython.compound([rings, planet]) self.body.pos = v(*self.pos) self.body.axis = v(0, 1, 2) else: if simple: self.body = vpython.simple_sphere(pos=v(*self.pos), radius=dradius * dispmult, color=color, up=v(*up)) else: self.body = vpython.sphere(pos=v(*self.pos), radius=dradius * dispmult, color=color, texture=texture, up=v(*up)) self.body.cradius = self.rad * capmult self.body.mass = self.M
def gettile(offsets=None, cpos=None): """Create and return a list of 3D objects making up a single MWA tile. If cpos is given, it's used as the center position for the whole tile (if you want to show multiple tiles). """ if offsets is None: offsets = TILEOFFSETS if cpos is None: cpos = v(0, 0, 0) elif type(cpos) == tuple: cpos = v(cpos) eaxis = vpython.arrow(pos=v(0, 0, 0), axis=v(3, 0, 0), color=color.blue, shaftwidth=0.1, fixedwidth=True, opacity=0.2) naxis = vpython.arrow(pos=v(0, 0, 0), axis=v(0, 3, 0), color=color.blue, shaftwidth=0.1, fixedwidth=True, opacity=0.2) eaxislabel = vpython.text(text='E', pos=v(3, 0, 0.2), height=0.5, depth=0.1, color=color.blue, opacity=0.2) naxislabel = vpython.text(text='N', pos=v(0, 3, 0.2), height=0.5, depth=0.1, color=color.blue, opacity=0.2) gp = vpython.box(pos=v(0, 0, 0) + cpos, axis=v(0, 0, 1), height=5.0, width=5.0, length=0.05, color=color.gray(0.5)) olist = [eaxis, naxis, eaxislabel, naxislabel, gp] letters = 'ABCDEFGHIJKLMNOP' for i in range(16): xy = offsets[i] p = v(xy[0], xy[1], 0) + cpos dlist = getdipole(cpos=p, dlabel=letters[i]) olist += dlist return olist
def getedadelays(offsets=EDAOFFSETS, az=0.0, el=90.0): """Create and return 3D objects representing the pointing delays for all 256 EDA dipoles. They are represented by arrows for each dipole, with a length equal to that dipoles delay value times the speed of light, and all point at the specified az/el direction. Positive delays are represented by arrows below the ground plane, negative delays are represented by arrows the ground plane. Two sets of delays are shown - the ideal gemetric delays are shown in white, and the actual integer delays (the sum of the first and second stage delays) are shown in green. A tuple of (parrow, ilist, alist) is returned, where 'parrow' is a single, long, yellow arrow from the centre of the EDA showing the pointing direction, ilist is the list of 'ideal' delay arrows, and 'alist' is the list of 'actual' delay arrows. They are returned separately, so the 'visible' attribute on each set of arrows can be set as needed. """ if ONLYBFs is not None: clipdelays = False else: clipdelays = True idelays, diagnostics = pointing.calc_delays(offsets=offsets, az=az, el=el, strict=STRICT, verbose=True, clipdelays=clipdelays, cpos=CPOS) if diagnostics is not None: delays, delayerrs, sqe, maxerr, offcount = diagnostics if offcount > 0: print( 'Elevation low - %d dipoles disabled because delays were too large to reach in hardware.' % offcount) else: delays, delayerrs, sqe, maxerr, offcount = None, None, None, None, None if idelays is None: print("Error calculating delays for az=%s, el=%s" % (az, el)) return [] if ONLYBFs is None: offcount = 0 for bfid in pointing.HEXD: for dipid in pointing.HEXD: if idelays[bfid][dipid] == 16: # disabled offcount += 1 elif len( ONLYBFs ) == 1: # We only have one beamformer enabled, so disable all other dipoles and normalise remaining to the minimum delay on that BF offcount = 240 print( "Only one first stage beamformer enabled (%s) and delays normalised to the minimum value, other 240 dipoles are disabled!" % ONLYBFs) for bfid in pointing.HEXD: if bfid in ONLYBFs: # If this is one of the beamformer we want to point: mind = min(idelays[bfid].values() ) # Find the smallest delay in this BF for dipid in pointing.HEXD: idelays[bfid][dipid] -= ( mind + 16 ) # Subtract the minimum delay from the given delay, then subtract 16 if (idelays[bfid][dipid] < -16) or (idelays[bfid][dipid] > 15): idelays[bfid][dipid] = 16 # Disabled offcount += 1 else: for dipid in pointing.HEXD: idelays[bfid][ dipid] = 16 # Disable all dipoles on other beamformers else: offcount = 0 print( "Only some first stage beamformer enabled (%s), other %d dipoles are disabled!" % (ONLYBFs, offcount)) for bfid in pointing.HEXD: for dipid in pointing.HEXD: if bfid in ONLYBFs: if (idelays[bfid][dipid] < -16) or (idelays[bfid][dipid] > 15): idelays[bfid][dipid] = 16 # Disabled offcount += 1 else: idelays[bfid][dipid] = 16 # Disabled offcount += 1 north = v(0, 1, 0) # Due north, elevation 0 degrees t1 = vpython.rotate(north, angle=(el * math.pi / 180.0), axis=v( 1, 0, 0)) # Rotate up (around E/W axis) by 'el' degrees pvector = vpython.rotate( t1, angle=(-az * math.pi / 180.0), axis=v(0, 0, 1)) # Rotate clockwise by 'az' degrees around 'up' axis parrow = vpython.arrow(pos=v(0, 0, 0), axis=pvector, color=color.yellow, length=20.0, shaftwidth=1.0, visible=True) ilist = [] alist = [] dlist = [] for bfid in pointing.HEXD: for dipid in pointing.HEXD: # Arrow lengths are negative if delays are positive, and vice/versa if delays: idealdelay = delays[bfid][dipid] * pointing.C ilist.append( vpython.arrow(pos=v(*offsets[bfid][dipid]), axis=pvector, length=-idealdelay, color=color.white, shaftwidth=0.2, visible=ivis)) if idelays[bfid][dipid] != 16: # If this dipole isn't disabled actualdelay = ( (idelays[bfid][dipid] * pointing.MSTEP) + (idelays['K'][bfid] * pointing.KSTEP)) * pointing.C alist.append( vpython.arrow(pos=v(*offsets[bfid][dipid]), axis=pvector, length=-actualdelay, color=color.green, shaftwidth=0.2, visible=avis)) delaydifference = idealdelay - actualdelay dlist.append( vpython.arrow(pos=v(*offsets[bfid][dipid]), axis=pvector, length=100 * delaydifference, color=color.red, shaftwidth=0.2, visible=dvis)) return parrow, ilist, alist, dlist
def getdipole(cpos=None): width = 0.35 # Center to edge of batwing height = 0.4 # Top of batwing corner to ground standoff = 0.1 # ground to bottom of batwing triangle cylen = 0.15 # length of LNA cylinder cydia = 0.15 # diameter of LNA cylinder cpoint = v(0, 0, (height / 2.0 + standoff)) boxw = 0.05 # thickness of dipole arms tubeoff = standoff # gap between bottom of wire tube and the ground if cpos is None: cpos = v((0, 0, 0)) elif type(cpos) == tuple: cpos = v(cpos) xl = vpython.box(pos=v(-width, 0, (height + standoff) / 2) + cpos, axis=v(0, 0, 1), height=boxw, width=boxw, length=height + boxw, color=vpython.color.gray(0.8), visible=False) xlt = vpython.box(pos=v(0, 0, cpoint.z) + cpos, axis=(v(width, 0, standoff) - v(-width, 0, height)), height=boxw, width=boxw, color=vpython.color.gray(0.8), visible=False) xlb = vpython.box(pos=v(0, 0, cpoint.z) + cpos, axis=(v(width, 0, height) - v(-width, 0, standoff)), height=boxw, width=boxw, color=vpython.color.gray(0.8), visible=False) xr = vpython.box(pos=v(width, 0, (height + standoff) / 2) + cpos, axis=v(0, 0, 1), height=boxw, width=boxw, length=height + boxw, color=vpython.color.gray(0.8), visible=False) yl = vpython.box(pos=v(0, -width, (height + standoff) / 2) + cpos, axis=v(0, 0, 1), height=boxw, width=boxw, length=height + boxw, color=vpython.color.gray(0.8), visible=False) ylt = vpython.box(pos=v(0, 0, cpoint.z) + cpos, axis=(v(0, width, standoff) - v(0, -width, height)), height=boxw, width=boxw, color=vpython.color.gray(0.8), visible=False) ylb = vpython.box(pos=v(0, 0, cpoint.z) + cpos, axis=(v(0, width, height) - v(0, -width, standoff)), height=boxw, width=boxw, color=vpython.color.gray(0.8), visible=False) yr = vpython.box(pos=v(0, width, (height + standoff) / 2) + cpos, axis=v(0, 0, 1), height=boxw, width=boxw, length=height + boxw, color=vpython.color.gray(0.8), visible=False) lna = vpython.cylinder(pos=v(0, 0, cpoint.z - cylen / 2) + cpos, axis=v(0, 0, cylen), radius=cydia / 2.0, color=color.white, visible=False) # tube = vpython.cylinder(pos=v(0,0,tubeoff) + cpos, radius=boxw/2.0, axis=(0,0,cpoint.z-standoff), color=color.white, visible=False) return [xl, xlt, xlb, xr, yl, ylt, ylb, yr, lna]
def plot(tiles=None, pads=None): global simplist, complist, pdict, scene scene.autocenter = False # Disable autocentering and point the camera at the origin to start scene.center = v(0, 0, 0) scene.show_rendertime = True # Draw a transparent grey ground plane, and transparent blue axis arrows and labels ground = vpython.box(pos=v(0, 0, 0), length=3000, height=3000, width=0.1, color=v(0.8, 0, 0), opacity=0.2) eaxis = vpython.arrow(pos=v(0, 0, 0), axis=v(1600, 0, 0), color=color.blue, shaftwidth=2, fixedwidth=True, opacity=0.2) eaxislabel = vpython.label(text='East', pos=v(1580, 20, 0), color=color.blue) naxis = vpython.arrow(pos=v(0, 0, 0), axis=v(0, 1600, 0), color=color.blue, shaftwidth=2, fixedwidth=True, opacity=0.2) naxislabel = vpython.label(text='North', pos=v(20, 1580, 0), color=color.blue) # aaxis = vpython.arrow(pos=(0,0,0), axis=(0,0,100), color=color.blue, shaftwidth=2, fixedwidth=True, opacity=0.2) # aaxislabel = vpython.label(text='Up', pos=(0,20,80), color=color.blue) for tile in tiles: # complist += gettile(cpos=v(tile.east, tile.north, 0.0)) simplist.append( vpython.box(pos=v(tile.east, tile.north, 0.0), axis=v(0, 0, 1), height=5.0, width=5.0, length=0.2, color=color.green)) simplist[-1].name = tile.name for pad in pads: pobj = vpython.box(pos=v(pad.east, pad.north, 0.0), length=1.0, height=2.0, width=1.0, color=color.white) if not pad.enabled: pobj.color = v(0.5, 0.5, 0.5) num = int(''.join([c for c in pad.name if c.isdigit()])) if divmod(num, 2)[1] == 0: xoffset = 12 else: xoffset = -12 if pad.name.endswith('a'): yoffset = -8 else: yoffset = 8 # pobj.label = vpython.label(pos=pobj.pos, text=pad.name, xoffset=xoffset, yoffset=yoffset, box=False, line=False, opacity=0.2) pobj.label = vpython.label(pos=v(pobj.pos.x + xoffset, pobj.pos.y + yoffset, pobj.pos.z + 10), text=pad.name, height=15) pobj.cables = {} for tname, tdata in pad.inputs.items(): tpos = v(tdata[0].east, tdata[0].north, 0.0) cobj = vpython.arrow(pos=pobj.pos, axis=(tpos - pobj.pos), shaftwidth=ARROWWIDTH, fixedwidth=True) pobj.cables[tname] = cobj pdict[pad.name] = pobj # Bind mouse click events and key presses to the callback function scene.bind('mousedown', processClick)
# # Andrew Williams, 2002 # # Toggle 'pause' mode with the space bar key. import vpython from vpython import vector as v import math import time win = 700 scene = vpython.canvas(title="Moon's Orbit", width=win, height=win) scene.lights = [] scene.ambient = vpython.color.gray(0.1) sunlight = [ vpython.distant_light(direction=v(-1, 0, 0), color=v(1.0, 1.0, 1.0)), vpython.distant_light(direction=v(-1, 0, 0), color=v(1.0, 1.0, 1.0)), vpython.distant_light(direction=v(-1, 0, 0), color=v(1.0, 1.0, 1.0)) ] starteaxis = v(1, 0, 0) earth = vpython.sphere(texture=vpython.textures.earth, up=v(0, 0, 1), axis=starteaxis) earth.pos = v(0, 0, 0) earth.radius = 1.5 earth.rotperiod = 1.0 moon = vpython.sphere() moon.radius = 0.5 moon.color = vpython.color.gray(0.3)
Nstars = 300 # change this to have more or fewer stars G = 6.7e-11 # Universal gravitational constant # Typical values Msun = 2E30 # 1 solar mass, in kg Rsun = 1E10 # approx 7 solar radii Rtrail = 2e8 L = 4e11 vsun = 0.2 * math.sqrt(G * Msun / Rsun) scene = vpython.canvas(title="Stars", width=win, height=win, range=2 * L, forward=v(-1, -1, -1)) xaxis = vpython.curve(pos=[v(0, 0, 0), v(L, 0, 0)], color=v(0.5, 0.5, 0.5)) yaxis = vpython.curve(pos=[v(0, 0, 0), v(0, L, 0)], color=v(0.5, 0.5, 0.5)) zaxis = vpython.curve(pos=[v(0, 0, 0), v(0, 0, L)], color=v(0.5, 0.5, 0.5)) Stars = [] colors = [ vpython.color.red, vpython.color.green, vpython.color.blue, vpython.color.yellow, vpython.color.cyan, vpython.color.magenta ] poslist = [] plist = [] mlist = [] rlist = []
dest='diffs', default=False, action='store_true', help="Show the differences between the ideal and actual delay values") (options, args) = parser.parse_args() mode = 'EDA' showlabels = False if options.tile: mode = 'TILE' showlabels = True elif options.labels: showlabels = True scene = vpython.canvas(width=1600, height=1000) scene.forward = v(0, 1, -1) scene.up = v(0, 0, 1) if mode == 'EDA': scene.range = 25 else: scene.range = 5 az = el = None if (options.az is not None) and (options.el is not None): az = float(options.az) el = float(options.el) if options.onlybfs: if options.onlybfs.upper() == 'ALL': ONLYBFs = None else:
import vpython from vpython import vector as v win = 1000 scene = vpython.canvas(title="Orbit", width=win, height=win, range=4e11) giant = vpython.sphere() giant.pos = v(-1e11, 0, 0) giant.radius = 2e10 giant.color = vpython.color.red giant.mass = 2e30 giant.p = v(0, 0, -1e4) * giant.mass dwarf = vpython.sphere() dwarf.pos = v(1.5e11, 0, 0) dwarf.radius = 1e10 dwarf.color = vpython.color.yellow dwarf.mass = 1e30 dwarf.p = -giant.p giant.orbit = vpython.curve(color=giant.color, radius=2e9) dwarf.orbit = vpython.curve(color=dwarf.color, radius=2e9) dt = 86400 autoscale = 0 autocenter = 0 while 1: vpython.rate(100)
# the sun. # # Hopelessly out of proper scale, of course, it's meant to illustrate the motion # # Andrew Williams, 2002 import vpython from vpython import vector as v import math import time win = 700 scene = vpython.canvas(title="Mercury's Orbit", width=win, height=win) sun = vpython.sphere() sun.pos = v(0, 0, 0) sun.radius = 1.5 sun.color = vpython.color.yellow planet = vpython.sphere() planet.radius = 0.5 planet.color = vpython.color.red planet.a = 5 # Semi-major axis planet.e = 0.20562 # eccentricity of orbit (0=circle) planet.pos = v(planet.a * (1 - planet.e), 0, 0) startpos = v(planet.a * (1 - planet.e), 0, 0) planet.sidperiod = 87.97 # Sidereal Period (planet's year, in Earth days) planet.rotperiod = 58.6462 # Length of the planets sidereal day, in Earth days parrow = vpython.arrow(pos=planet.pos, axis=v(-1, 0, 0))
def ProcessKeys(event): """Handle any keystrokes during the model. """ global paused, Tracking, scenecenter, TrackAngle, TrackMag, scene, tlabel, Trail try: # Key pressed: k = event.key if ( k == '0' ) and 'Sun' in PlanetsToModel: # Keys 0-9 keep the view centered on Sun-Pluto respectively scenecenter = bodies['Sun'] elif (k == '1') and 'Mercury' in PlanetsToModel: scenecenter = bodies['Mercury'] elif (k == '2') and 'Venus' in PlanetsToModel: scenecenter = bodies['Venus'] elif (k == '3') and 'Earth' in PlanetsToModel: scenecenter = bodies['Earth'] elif (k == '4') and 'Mars' in PlanetsToModel: scenecenter = bodies['Mars'] elif (k == '5') and 'Jupiter' in PlanetsToModel: scenecenter = bodies['Jupiter'] elif (k == '6') and 'Saturn' in PlanetsToModel: scenecenter = bodies['Saturn'] elif (k == '7') and 'Uranus' in PlanetsToModel: scenecenter = bodies['Uranus'] elif (k == '8') and 'Neptune' in PlanetsToModel: scenecenter = bodies['Neptune'] elif (k == '9') and 'Pluto' in PlanetsToModel: scenecenter = bodies['Pluto'] elif ( k == 't' ): # If tracking is on, keep the same viewpoint when following an object print("'t' pressed, Tracking=%s, TrackAngle=%s" % (Tracking, TrackAngle)) if not Tracking: bvec = v(*nbody.hp[scenecenter.i]).norm() TrackAngle = scene.camera.axis.norm() - bvec TrackMag = scene.camera.axis.mag Tracking = True print("Tracking") else: Tracking = False print("Not Tracking") elif k == 'u': if scene.up == v(0, 0, 1): scene.up = v(0, 1, 0) else: scene.up = v(0, 0, 1) elif k == 'b': # Up and down arrows scale the displayed object sizes up and down scalesizes(1.2) elif k == 's': scalesizes(0.8) elif (k == 'p' ): # Toggle the display of orbital paths and dots behind objects if paused: paused = False print('Resumed') else: paused = True print('Paused') elif (k == 'c'): if Trail is not None: Trail.clear() Trail.stop() Trail = None elif (k == 'e' ): # Show differences between modelled and ephemeris positions ShowErrors() if k in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']: # New scene center object, update display window scene.center = scenecenter.body.pos tlabel.pos = scene.center except: # Mouse click print("Exception in ProcessKeys: %s" % traceback.format_exc()) pass
Nasteroids = 1000 # Number of random asteroids RandomA = False # If false, the semi-major axes for all asteroids are evenly distributed, instead of random rpos = 12 # Start angle for orbital position, in degrees ('None' for random positions) amin, amax = 3.0, 5.5 # bounds for semi-major axis distribution emin, emax = 0.0, 0.00 # Bounds for eccentricity variation (zero for circular orbits) Imin, Imax = -0.0, 0.0 # Bounds for inclination angle variation, in degrees (zero for orbits in the plane of the ecliptic) ############################ Set up display window and lighting #################################### win = 800 # Display window size, in pixels scene = vpython.canvas(title="Orbit", width=win, height=win) # Create window scene.lights = [] # Dump default scene lighting scene.ambient = vpython.color.gray(0.3) # Low level ambient lighting sunlight = vpython.local_light(pos=v( 0, 0, 0), color=vpython.color.white) # Sunlight from centre ########################### Class and function definitions ############################################# class Body(planephem.Planet): """Subclass the 'Planet' object in the ephemeris library to add methods for setting up the 3D Visual Python objects to display it. """ def __init__(self, *args, **keywords): planephem.Planet.__init__(self, *args, **keywords) self.color = vpython.color.white self.dradius = 1.0 self.texture = None self.rings = False self.up = (0, 0, 1) self.body = None
def getdipole(cpos=None, dlabel=None): """Creates and returns a list of 3D objects making up a single MWA dipole. If cpos is given, it must be a vpython.vector object used for the center of the dipole (actually the point on the ground directly underneath the LNA tube). If dlabel is given, it must be a one or two letter label to draw on the top of the LNA tube.""" width = 0.35 # Center to edge of batwing height = 0.4 # Top of batwing corner to ground standoff = 0.1 # ground to bottom of batwing triangle cylen = 0.15 # length of LNA cylinder cydia = 0.15 # diameter of LNA cylinder cpoint = v(0, 0, (height / 2.0 + standoff)) boxw = 0.02 # thickness of dipole arms tubeoff = standoff # gap between bottom of wire tube and the ground if cpos is None: cpos = v(0, 0, 0) elif type(cpos) == tuple: cpos = v(cpos) xl = vpython.box(pos=v(-width, 0, (height + standoff) / 2) + cpos, axis=v(0, 0, 1), height=boxw, width=boxw, length=height + boxw, color=vpython.color.gray(0.8)) xlt = vpython.box(pos=v(0, 0, cpoint.z) + cpos, axis=(v(width, 0, standoff) - v(-width, 0, height)), height=boxw, width=boxw, color=vpython.color.gray(0.8)) xlb = vpython.box(pos=v(0, 0, cpoint.z) + cpos, axis=(v(width, 0, height) - v(-width, 0, standoff)), height=boxw, width=boxw, color=vpython.color.gray(0.8)) xr = vpython.box(pos=v(width, 0, (height + standoff) / 2) + cpos, axis=v(0, 0, 1), height=boxw, width=boxw, length=height + boxw, color=vpython.color.gray(0.8)) yl = vpython.box(pos=v(0, -width, (height + standoff) / 2) + cpos, axis=v(0, 0, 1), height=boxw, width=boxw, length=height + boxw, color=vpython.color.gray(0.8)) ylt = vpython.box(pos=v(0, 0, cpoint.z) + cpos, axis=(v(0, width, standoff) - v(0, -width, height)), height=boxw, width=boxw, color=vpython.color.gray(0.8)) ylb = vpython.box(pos=v(0, 0, cpoint.z) + cpos, axis=(v(0, width, height) - v(0, -width, standoff)), height=boxw, width=boxw, color=vpython.color.gray(0.8)) yr = vpython.box(pos=v(0, width, (height + standoff) / 2) + cpos, axis=v(0, 0, 1), height=boxw, width=boxw, length=height + boxw, color=vpython.color.gray(0.8)) lna = vpython.cylinder(pos=v(0, 0, cpoint.z - cylen / 2) + cpos, axis=v(0, 0, cylen), radius=cydia / 2.0, color=color.white) tube = vpython.cylinder(pos=v(0, 0, tubeoff) + cpos, radius=boxw / 2.0, axis=v(0, 0, cpoint.z - standoff), color=color.white) olist = [xl, xlt, xlb, xr, yl, ylt, ylb, yr, lna, tube] if dlabel and showlabels: lnalabel = vpython.text(text=dlabel, pos=lna.pos + lna.axis + v(-0.035 * len(dlabel), -0.035, 0), height=0.07, depth=0.01, color=color.black) olist.append(lnalabel) return olist
def gettiledelays(cpos=None, az=0.0, el=90.0): """ Copied from function calc_delays in obssched/pycontroller.py, with code to create the actual arrow objects added. If cpos is given, it's used as the tile centre position - use this when showing more than one tile. Algorithm copied from ObsController.java and converted to Python This function takes in an azimuth and zenith angle as inputs and creates and returns a 16-element byte array for delayswitches which have values corresponding to each dipole in the tile having a maximal coherent amplitude in the desired direction. This will return null if the inputs are out of physical range (if za is bigger than 90) or if the calculated switches for the dipoles are out of range of the delaylines in the beamformer. azimuth of 0 is north and it increases clockwise zenith angle is the angle down from zenith These angles should be given in degrees Layout of the dipoles on the tile: N 0 1 2 3 4 5 6 7 W E 8 9 10 11 12 13 14 15 S """ if cpos is None: cpos = v(0, 0, 0) elif type(cpos) == tuple: cpos = v(cpos) # Find the delay values for the nearest sweetspot, to use for green arrows: sweetaz, sweetel, sweetdelays = get_sweet_delays(az=az, el=el) # Calculate the geometric delays for the ax/el given, without using sweetspot dip_sep = 1.10 # dipole separations in meters delaystep = 435.0 # Delay line increment in picoseconds maxdelay = 31 # Maximum number of deltastep delays c = 0.000299798 # C in meters/picosecond dtor = math.pi / 180.0 # convert degrees to radians # define zenith angle za = 90 - el # Define arrays to hold the positional offsets of the dipoles xoffsets = [0.0] * 16 # offsets of the dipoles in the W-E 'x' direction yoffsets = [0.0] * 16 # offsets of the dipoles in the S-N 'y' direction delays = [0.0] * 16 # The calculated delays in picoseconds rdelays = [0] * 16 # The rounded delays in units of delaystep delaysettings = [0] * 16 # return values # Check input sanity if (abs(za) > 90): return None # Offsets of the dipoles are calculated relative to the # center of the tile, with positive values being in the north # and east directions xoffsets[0] = -1.5 * dip_sep xoffsets[1] = -0.5 * dip_sep xoffsets[2] = 0.5 * dip_sep xoffsets[3] = 1.5 * dip_sep xoffsets[4] = -1.5 * dip_sep xoffsets[5] = -0.5 * dip_sep xoffsets[6] = 0.5 * dip_sep xoffsets[7] = 1.5 * dip_sep xoffsets[8] = -1.5 * dip_sep xoffsets[9] = -0.5 * dip_sep xoffsets[10] = 0.5 * dip_sep xoffsets[11] = 1.5 * dip_sep xoffsets[12] = -1.5 * dip_sep xoffsets[13] = -0.5 * dip_sep xoffsets[14] = 0.5 * dip_sep xoffsets[15] = 1.5 * dip_sep yoffsets[0] = 1.5 * dip_sep yoffsets[1] = 1.5 * dip_sep yoffsets[2] = 1.5 * dip_sep yoffsets[3] = 1.5 * dip_sep yoffsets[4] = 0.5 * dip_sep yoffsets[5] = 0.5 * dip_sep yoffsets[6] = 0.5 * dip_sep yoffsets[7] = 0.5 * dip_sep yoffsets[8] = -0.5 * dip_sep yoffsets[9] = -0.5 * dip_sep yoffsets[10] = -0.5 * dip_sep yoffsets[11] = -0.5 * dip_sep yoffsets[12] = -1.5 * dip_sep yoffsets[13] = -1.5 * dip_sep yoffsets[14] = -1.5 * dip_sep yoffsets[15] = -1.5 * dip_sep # First, figure out the theoretical delays to the dipoles # relative to the center of the tile # Convert to radians azr = az * dtor zar = za * dtor for i in range(16): # calculate exact delays in picoseconds from geometry... delays[i] = (xoffsets[i] * math.sin(azr) + yoffsets[i] * math.cos(azr)) * math.sin(zar) / c # Find minimum delay mindelay = min(delays) # Subtract minimum delay so that all delays are positive for i in range(16): delays[i] -= mindelay # Now minimize the sum of the deviations^2 from optimal # due to errors introduced when rounding the delays. # This is done by stepping through a series of offsets to # see how the sum of square deviations changes # and then selecting the delays corresponding to the min sq dev. # Go through once to get baseline values to compare bestoffset = -0.45 * delaystep minsqdev = 0 for i in range(16): delay_off = delays[i] + bestoffset intdel = int(round(delay_off / delaystep)) if (intdel > maxdelay): intdel = maxdelay minsqdev += math.pow((intdel * delaystep - delay_off), 2) minsqdev = minsqdev / 16 offset = (-0.45 * delaystep) + (delaystep / 20.0) while offset <= (0.45 * delaystep): sqdev = 0 for i in range(16): delay_off = delays[i] + offset intdel = int(round(delay_off / delaystep)) if (intdel > maxdelay): intdel = maxdelay sqdev = sqdev + math.pow((intdel * delaystep - delay_off), 2) sqdev = sqdev / 16 if (sqdev < minsqdev): minsqdev = sqdev bestoffset = offset offset += delaystep / 20.0 for i in range(16): rdelays[i] = int(round((delays[i] + bestoffset) / delaystep)) if (rdelays[i] > maxdelay): if (rdelays[i] > maxdelay + 1): return None # Trying to steer out of range. rdelays[i] = maxdelay # Set the actual delays for i in range(16): delaysettings[i] = int(rdelays[i]) if mode == 'EDA': parrowlen = 20.0 parrowsw = 1.0 else: parrowlen = 5.0 parrowsw = 0.2 north = v(0, 1, 0) # Due north, elevation 0 degrees at1 = vpython.rotate(north, angle=(el * math.pi / 180), axis=v( 1, 0, 0)) # Rotate up (around E/W axis) by 'el' degrees apvector = vpython.rotate( at1, angle=(-az * math.pi / 180), axis=v(0, 0, 1)) # Rotate clockwise by 'az' degrees around 'up' axis aarrow = vpython.arrow(pos=v(0, 0, 0), axis=apvector, color=color.white, length=parrowlen, shaftwidth=parrowsw, visible=avis) if (sweetaz is not None) and (sweetel is not None): st1 = vpython.rotate( north, angle=(sweetel * math.pi / 180), axis=v(1, 0, 0)) # Rotate up (around E/W axis) by 'el' degrees spvector = vpython.rotate( st1, angle=(-sweetaz * math.pi / 180), axis=v(0, 0, 1)) # Rotate clockwise by 'az' degrees around 'up' axis sarrow = vpython.arrow(pos=v(0, 0, 0), axis=spvector, color=color.green, length=parrowlen, shaftwidth=parrowsw, visible=avis) alist = [sarrow] else: alist = [] spvector = None ilist = [aarrow] dlist = [] for i in range(16): # Arrow lengths are negative if delays are positive, and vice/versa idealdelay = delaysettings[i] * TILEDELAYSTEP * pointing.C dposx, dposy = TILEOFFSETS[i] dpos = v(dposx, dposy, 0) + cpos if sweetdelays: sweetdelay = sweetdelays[i] * TILEDELAYSTEP * pointing.C alist.append( vpython.arrow(pos=dpos, axis=spvector, length=-sweetdelay, color=color.green, shaftwidth=0.2, visible=avis)) ilist.append( vpython.arrow(pos=dpos, axis=apvector, length=-idealdelay, color=color.white, shaftwidth=0.2, visible=avis)) # Tiles have two pointing arrows, stored in the 'alist' and 'ilist', so return None for the first element. return None, ilist, alist, dlist
"""Click once in the display window with the mouse, and a line will be drawn giant to dwarf star. Half a second later, a second line will be drawn. Use this to demonstrate that equal areas are swept out in equal times. """ import vpython from vpython import vector as v win = 1000 scene = vpython.canvas(title="Orbit", width=win, height=win, range=4e11, forward=v(0, -1, 0), up=v(-1, 0, 0)) giant = vpython.sphere() giant.pos = v(-1e11, 0, 0) giant.radius = 2e10 giant.color = vpython.color.red giant.mass = 1e30 giant.p = v(0, 0, -1e2) * giant.mass dwarf = vpython.sphere() dwarf.pos = v(1.5e11, 0, 0) dwarf.radius = 1e10 dwarf.color = vpython.color.yellow dwarf.mass = 1e28 dwarf.p = -giant.p giant.orbit = vpython.curve(color=giant.color, radius=2e9)
# # There's an opposition every 780 days, but the orbits are eccentric, so 'favourable' # oppositions, where mars is near perihelion, occur about every 15 years or so # # Andrew Williams, 2002 import vpython from vpython import vector as v import math import time win = 700 scene = vpython.canvas(title="Mars Orbit", width=win, height=win, range=2) sun = vpython.sphere() sun.pos = v(0, 0, 0) sun.radius = 0.2 sun.color = vpython.color.yellow earth = vpython.sphere() earth.radius = 0.07 earth.color = vpython.color.blue earth.a = 1.0 # Semi-major axis earth.e = 0.017 # eccentricity of orbit (0=circle) earth.pos = v(earth.a * (1 - earth.e), 0, 0) earthstart = v(earth.a * (1 - earth.e), 0, 0) earth.sidperiod = 365.246 # Sidereal Period (planet's year, in Earth days) mars = vpython.sphere() mars.radius = 0.035
# the sun. # # Hopelessly out of proper scale, of course, it's meant to illustrate the motion # # Andrew Williams, 2002 import vpython from vpython import vector as v import math import time win = 700 scene = vpython.canvas(title="Mercury's Orbit", width=win, height=win) earth = vpython.sphere() earth.pos = v(0, 0, 0) earth.radius = 1.5 earth.color = vpython.color.blue moon = vpython.sphere() moon.radius = 0.5 moon.color = vpython.color.red moon.a = 5 # Semi-major axis moon.e = 0.0 # eccentricity of orbit (0=circle) moon.pos = v(moon.a * (1 - moon.e), 0, 0) startpos = v(moon.a * (1 - moon.e), 0, 0) moon.sidperiod = 27.321661 # Sidereal Period (moon's 'year', in Earth days) moon.rotperiod = 27.321661 # Length of the planets sidereal day, in Earth days marrow = vpython.arrow(pos=moon.pos, axis=v(-1, 0, 0))
if lab: lab.visible = 0 lab = vpython.label(pos=pickobj.pos, xoffset=20, yoffset=20, text=pickobj.name) else: if lab: lab.visible = 0 scene = vpython.canvas(title="2367 Local Galaxies", width=win, height=win, range=30, forward=v(-1, -1, -1)) A = 3.0 xaxis = vpython.curve(pos=[v(0, 0, 0), (A, 0, 0)], color=v(0.5, 0.5, 0.5)) yaxis = vpython.curve(pos=[v(0, 0, 0), (0, A, 0)], color=v(0.5, 0.5, 0.5)) zaxis = vpython.curve(pos=[v(0, 0, 0), (0, 0, A)], color=v(0.5, 0.5, 0.5)) Stars = [ vpython.cylinder(pos=v(0, 0, 0), radius=30 / 100.0, color=v(1.0, 0.0, 0.0), length=30 / 1000.0, axis=v(0.0, 1.0, 0.0)) ] Stars[0].name = "Milky Way"