def line(pos=(0,0), np=2, rotate=0.0, scale=1.0, xscale=1.0, yscale=1.0, thickness=None, start=(0,0), end=(0,1), path=False): v = vis.vector((end[0]-start[0]), (end[1]-start[1])) if thickness is None: thickness = 0.01*vis.mag(v) dv = thickness*vis.norm(vis.vector(0,0,1).cross(v)) dx = dv.x dy = dv.y cp = [] # outer line cpi = [] # inner line vline = (vis.vector(end)-vis.vector(start)).norm() mline = vis.mag(vis.vector(end)-vis.vector(start)) for i in range(np): x = start[0] + (vline*i)[0]/float(np-1)*mline y = start[1] + (vline*i)[1]/float(np-1)*mline cp.append( (x+pos[0],y+pos[1]) ) cpi.append( (x+pos[0]+dx,y+pos[1]+dy) ) if not path: cpi.reverse() for p in cpi: cp.append(p) cp.append(cp[0]) if rotate != 0.0: cp = rotatecp(cp, pos, rotate) if scale != 1.0: xscale = yscale = scale pp = Polygon(cp) if xscale != 1.0 or yscale != 1.0: pp.scale(xscale,yscale) if not path: return pp else: return [cp]
def ship(s, v, a, dt, spaceship, predraw): dst = vector(0, 0, 0) - s # computing spaceship - Sun distance vector gravity_acc = (u / (mag2(dst))) * norm(dst) # computing gravity force v += (gravity_acc + a) * dt # numerical integration of velocity s += v * dt # numerical integration of position spaceship.pos = s # assigning new position to the spaceship spaceship.trail.append(pos=s, retain=2000) # appending spaceship trail with new position # recovers the spaceship to the initial position in case of crashing into the Sun or going out of range: if star_radius <= mag(s) or mag(s) <= sun_radius: spaceship.pos = s0 spaceship.trail.pos = [] # clear the trail s, v, a = vector(s0.astuple()), vector(v0.astuple()), vector(a0.astuple()) # assign initial values predraw = False # redraw the orbital prediction return s, v, a, predraw
def ship(s, v, a, dt, spaceship, predraw): dst = vector(0, 0, 0) - s # computing spaceship - Sun distance vector gravity_acc = (u / (mag2(dst))) * norm(dst) # computing gravity force v += (gravity_acc + a) * dt # numerical integration of velocity s += v * dt # numerical integration of position spaceship.pos = s # assigning new position to the spaceship spaceship.trail.append( pos=s, retain=2000) # appending spaceship trail with new position # recovers the spaceship to the initial position in case of crashing into the Sun or going out of range: if star_radius <= mag(s) or mag(s) <= sun_radius: spaceship.pos = s0 spaceship.trail.pos = [] # clear the trail s, v, a = vector(s0.astuple()), vector(v0.astuple()), vector( a0.astuple()) # assign initial values predraw = False # redraw the orbital prediction return s, v, a, predraw
def lbl_ship(popup, obj, s, v, a): # get magnitudes of distance from the Sun, velocity and acceleration: r0mag = mag(s) v0mag = mag(v) a0mag = mag(a) * 1e6 # converted from km/s^2 to m/s^2 eps = mag2(v) / 2 - u / r0mag # compute specific orbital energy popup.pos = obj.pos # update label position to overlap with spaceship position # update label text with new data: popup.text = "Spaceship!" + \ "\nAcceleration: " + str(a) + \ "\nSpecific orbital energy: " + str(eps) + " MJ/kg" + \ "\nDistance from the Sun: " + str(int(round(r0mag))) + " km (" + str( round(r0mag / 149598261, 2)) + " AU)" + \ "\nEngine Acceleration: " + str(round(a0mag, 2)) + " m/s^2" + \ "\nOrbital Velocity: " + str(round(v0mag, 2)) + " km/s" popup.visible = True return popup
def lbl(popup, obj, sw_lbl, dt): # global variables for comparison between function calls global obj_global, a_global, eps_global, name_global, radius_global err = 1e20 # large number for error comparison in the for loop below r0mag = mag(obj.pos) # computing the instantaneous distance from the Sun if r0mag == 0: # turning off the planet label if the clicked object is centered at the origin (i.e. Sun, stars) sw_lbl = not sw_lbl return popup, sw_lbl if obj_global != obj: # execute only if new object was chosen # looking through the planet list searching for the closest value for semi major axis for the selected object: for planet in planet_list: if (abs(planet['a'] - r0mag)) < err: err = (abs(planet['a'] - r0mag)) # assign new closest value a_global = planet['a'] # assign semi-major axis name_global = planet['name'] # assign planet name radius_global = planet['radius'] # assign planet radius eps_global = -u / (2 * a_global ) # compute specific orbital energy obj_global = obj # assign new object as already labeled v0mag = (2 * (eps_global + u / r0mag) )**0.5 # velocity calculation using specific orbital energy popup.pos = obj.pos # update label position to overlap with planet position # update label text with new data: popup.text = str(name_global) + \ "\nRadius: " + str(radius_global) + " km" + \ "\nDistance from the Sun: " + str(int(round(r0mag))) + " km (" + str( round(r0mag / 149598261, 2)) + " AU)" + \ "\nOrbital Velocity: " + str(round(v0mag, 2)) + " km/s" + \ "\nTime scale: 1 s = " + str(round(f * dt * 365.25 * 86400 / (3600. * n), 3)) + "hrs" popup.visible = True return popup, sw_lbl
def lbl(popup, obj, sw_lbl, dt): # global variables for comparison between function calls global obj_global, a_global, eps_global, name_global, radius_global err = 1e20 # large number for error comparison in the for loop below r0mag = mag(obj.pos) # computing the instantaneous distance from the Sun if r0mag == 0: # turning off the planet label if the clicked object is centered at the origin (i.e. Sun, stars) sw_lbl = not sw_lbl return popup, sw_lbl if obj_global != obj: # execute only if new object was chosen # looking through the planet list searching for the closest value for semi major axis for the selected object: for planet in planet_list: if (abs(planet['a'] - r0mag)) < err: err = (abs(planet['a'] - r0mag)) # assign new closest value a_global = planet['a'] # assign semi-major axis name_global = planet['name'] # assign planet name radius_global = planet['radius'] # assign planet radius eps_global = -u / (2 * a_global) # compute specific orbital energy obj_global = obj # assign new object as already labeled v0mag = (2 * (eps_global + u / r0mag)) ** 0.5 # velocity calculation using specific orbital energy popup.pos = obj.pos # update label position to overlap with planet position # update label text with new data: popup.text = str(name_global) + \ "\nRadius: " + str(radius_global) + " km" + \ "\nDistance from the Sun: " + str(int(round(r0mag))) + " km (" + str( round(r0mag / 149598261, 2)) + " AU)" + \ "\nOrbital Velocity: " + str(round(v0mag, 2)) + " km/s" + \ "\nTime scale: 1 s = " + str(round(f * dt * 365.25 * 86400 / (3600. * n), 3)) + "hrs" popup.visible = True return popup, sw_lbl
def roundc(cp, roundness=0.1, nseg=8, invert=False): vort = 0.0 cp.pop() for i in range(len(cp)): i1 = (i+1)%len(cp) i2 = (i+2)%len(cp) v1 = vis.vector(cp[i1]) - vis.vector(cp[i]) v2 = vis.vector(cp[(i2)%len(cp)]) - vis.vector(cp[i1]) dv = vis.dot(v1,v2) vort += dv if vort > 0: cp.reverse() l = 999999 for i in range(len(cp)): p1 = vis.vector(cp[i]) p2 = vis.vector(cp[(i+1)%len(cp)]) lm = vis.mag(p2-p1) if lm < l: l = lm r = l*roundness ncp = [] lcp = len(cp) for i in range(lcp): i1 = (i+1)%lcp i2 = (i+2)%lcp w0 = vis.vector(cp[i]) w1 = vis.vector(cp[i1]) w2 = vis.vector(cp[i2]) wrt = vis.cross((w1-w0),(w2-w0)) v1 = w1-w0 v2 = w1-w2 rax = vis.norm(((vis.norm(v1)+vis.norm(v2))/2.0)) angle = acos(vis.dot(vis.norm(v2),vis.norm(v1))) afl = 1.0 if wrt[2] > 0: afl = -1.0 angle2 = angle/2.0 cc = r/sin(angle2) ccp = vis.vector(cp[i1]) - rax*cc tt = r/tan(angle2) t1 = vis.vector(cp[i1]) -vis.norm(v1)*tt t2 = vis.vector(cp[i1]) -vis.norm(v2)*tt ncp.append(tuple(t1)[0:2]) nc = [] a = 0 dseg = afl*(pi-angle)/nseg if not invert: for i in range(nseg): nc.append(rotatep(t1, ccp, a)) ncp.append(tuple(nc[-1])[0:2]) a -= dseg else: dseg = afl*(angle)/nseg for i in range(nseg): nc.append(rotatep(t1, (cp[i1][0],cp[i1][1],0), a)) ncp.append(tuple(nc[-1])[0:2]) a += dseg ncp.append(tuple(t2)[0:2]) ncp.append(ncp[0]) return ncp