Create simulation of Earth revolving around sun in vpython - physics

I have to create a simple simulation of the Earth revolving around the sun. I can't use spherical coordinates, I have to use gravitational energy and velocity equations So far I have this:
earth = sphere (color = color.green, radius = 10**6)
sun = sphere (color = color.yellow, radius = 10**7)
earth.mass = 5.972*10**24
sun.mass=1.989*10**30
d=1.496*10**8
v=(2*math.pi*d)/(3.154*10**7)
earth.velocity = vector(0.0, 0.0, -1*v)
earth.pos = vector(d, 0, 0)
sun.pos = vector(0,0,0)
dt = 50000
t = 0.0
P=0
while True:
rate(400)
f=(6.667*10**.11)*((earth.mass*sun.mass)/d**2)
P = P + f*dt
earth.velocity = P/earth.mass
earth.pos = earth.pos + earth.velocity*dt
t=t+dt
I don't know if I am missing something from the physics side or the coding but when I run it nothing shows up. Thanks in advance!

Two issues: Your rate statement must be indented, and with the momentum P initialized to 0 the Earth should fall into the Sun.

Related

Calculating the size of an object using opencv and numpy poly1d

I'm looking to use a small numpy array to generate a curve that I can use to predict the height measurement at non-known points. I have several points that I am using to create a poly1d. I know it's possible, we use software that does it just fine at work, and when I used a different image as a tester, plugging the values into Excel and getting the polynomial, it worked fine, but I'm getting pretty drastic measurements on a different calibratable image, I get drastically different results.
Here is the image that I'm trying to measure.
The stick on the front of the pole contains known measurements. From bottom to top, they are 3'6" (42"), 6'6" (78"), 9' 8" (116"), 13' (156)
The picture has been through opencv undistort with a calibrated camera.
This is the function that actually performs the logic. x and y are gathered by cv2 EVENT_LBUTTONUP, and sent to this function.
Checking the lengths of the array is just to help me figure out why this isn't working, trying to generate a line to show the curve fit.
dist = self.firstClick-y
self.yData.append(dist)
if len(self.yData) > 4:
print(self.poly(dist))
if len(self.yData) == 4:
array = np.array(self.xData)
array = np.expand_dims(array, axis=0)
print(self.xData)
print(self.yData)
array=np.append(array, [self.yData], axis=0)
print(array)
x = array[:,0]
y = array[:,1]
self.poly = np.poly1d(np.polyfit(x, y, 2))
poly1d = np.poly1d(self.poly)
xp = np.linspace(-2, 20, 1)
_ = plt.plot(x, y, '.', xp, self.poly(xp), '-', xp, self.poly(xp), '--')
plt.ylim(0,200)
plt.show()
When I run this code, my values tend to quickly go into the tens of thousands when I'm attempting to collect the measurement at 18' 11", (the lowest wire).
Any help would be appreciated, I've been up all night trying to fit this curve.
Edit:
Sorry, I should have included the code used to display and scale the image.
self.img = cv2.imread(imagePath, cv2.IMREAD_ANYCOLOR)
self.scale_percent = 30
self.width = int(self.img.shape[1] * self.scale_percent/100)
self.height = int(self.img.shape[0] * self.scale_percent/100)
dsize = (self.width, self.height)
self.output = cv2.resize(self.img, dsize)
img = self.output
cv2.imshow('image', img)
cv2.setMouseCallback('image', self.click_event)
cv2.waitKey()
I just called this function to display the image and the below code to calibrate the values.
if self.firstClick == 0:
self.firstClick = y
cv2.putText(self.output, "Pole Base", (x, y), font, 1, (255, 255, 0), 2)
cv2.imshow('image', self.output)
elif self.firstClick != 0 and self.secondClick == 0:
self.secondClick = y
print("The difference in first and second clicks is", self.firstClick - self.secondClick)
first = self.firstClick - self.secondClick
inch = first/42
foot = inch*12
self.foot = foot
print("One foot is currently: ", foot)
self.firstLine = 3.5*12
self.secondLine = 6.5*12
self.thirdLine = 9.67*12
self.fourthLine = 13*12
self.xData = np.array([self.firstLine, self.secondLine, self.thirdLine, self.fourthLine])
self.yData.append(self.firstLine)
print(self.firstLine)
print(self.secondLine)
print(self.thirdLine)
print(self.fourthLine)

How to do FFT convolve? How to do normalization?

In Python, we can do a convolution by numpy.fft. For example, if we try to calculate gravitational lensing signal of the SIS model, we could define $\kappa$ as
$\kappa = \frac{\theta_{\rm E}}{2|\theta|}$,
then we can calculate deflection angle $\alpha$ by a convolution as $\alpha = \frac{1}{\pi} \int d\theta'^2 \kappa(\theta) \frac{\theta-\theta'}{|\theta-\theta'|}$ . Theoretically, deflection is $\alpha(\theta) = \theta_{\rm E}\frac{\theta}{|\theta|}$. But when I try to calculate that by numpy.fft, I am puzzled by some factors of normalization. For example,
npix = 2048 #mesh grid number
thetaE = 0.5 #a constant
dtheta = thetaE/10 #grid resolution
theta_x, theta_y, theta = mesh_theta(npix, dtheta) #assign grid position for calculation, theta will be an array of 2048*2048
kappa = thetaE/2./theta #define kappa mesh, 2048*2048
kern_alpha_x, kern_alpha_y = kernal_alpha(theta_x, theta_y) #define kernal mesh, 2048*2048
###zero padding should be used###
kappa_fft = np.fft.fft2(kappa)
kern_alpha_x_fft = np.fft.fft2(kern_alpha_x)
kern_alpha_y_fft = np.fft.fft2(kern_alpha_y)
alpha_x = np.fft.fftshift(np.fft.ifft2(kappa_fft*kern_alpha_x_fft)).real
alpha_y = np.fft.fftshift(np.fft.ifft2(kappa_fft*kern_alpha_y_fft)).real
As shown above, $\alpha_{\rm x}$, $\alpha_{\rm y}$ could be calculated by convolution between $\kappa$ and $K_{\alpha_{\rm x}}$, $K_{\alpha_{\rm y}}$, which means deflection $|\alpha| = \sqrt{\alpha_{\rm x}^2+\alpha_{\rm y}^2}$. However, when I check the results from alpha_x, alpha_y, it seems there is a normalization should be multiplied. If I multiply a factor as np.sqrt(alpha_x**2 + alpha_y**2)*dtheta*dtheta, then the result seems to be right. I do not know should this normalization dtheta*dthetamust be used and why? Thx.

Shortest rotation between two vectors not working like expected

def signed_angle_between_vecs(target_vec, start_vec, plane_normal=None):
start_vec = np.array(start_vec)
target_vec = np.array(target_vec)
start_vec = start_vec/np.linalg.norm(start_vec)
target_vec = target_vec/np.linalg.norm(target_vec)
if plane_normal is None:
arg1 = np.dot(np.cross(start_vec, target_vec), np.cross(start_vec, target_vec))
else:
arg1 = np.dot(np.cross(start_vec, target_vec), plane_normal)
arg2 = np.dot(start_vec, target_vec)
return np.arctan2(arg1, arg2)
from scipy.spatial.transform import Rotation as R
world_frame_axis = input_rotation_object.apply(canonical_axis)
angle = signed_angle_between_vecs(canonical_axis, world_frame_axis)
axis_angle = np.cross(world_frame_axis, canonical_axis) * angle
C = R.from_rotvec(axis_angle)
transformed_world_frame_axis_to_canonical = C.apply(world_frame_axis)
I am trying to align world_frame_axis to canonical_axis by performing a rotation around the normal vector generated by the cross product between the two vectors, using the signed angle between the two axes.
However, this code does not work. If you start with some arbitrary rotation as input_rotation_object you will see that transformed_world_frame_axis_to_canonical does not match canonical_axis.
What am I doing wrong?
not a python coder so I might be wrong but this looks suspicious:
start_vec = start_vec/np.linalg.norm(start_vec)
from the names I would expect that np.linalg.norm normalizes the vector already so the line should be:
start_vec = np.linalg.norm(start_vec)
and all the similar lines too ...
Also the atan2 operands are not looking right to me. I would (using math):
a = start_vec / |start_vec | // normalized start
b = target_vec / |target_vec| // normalized end
u = a // normalized one axis of plane
v = cross(u ,b)
v = cross(v ,u)
v = v / |v| // normalized second axis of plane perpendicular to u
dx = dot(u,b) // target vector in 2D aligned to start
dy = dot(v,b)
ang = atan2(dy,dx)
beware the ang might negated (depending on your notations) if the case either add minus sign or reverse the order in cross(u,v) to cross(v,u) Also you can do sanity check with comparing result to unsigned:
ang' = acos(dot(a,b))
in absolute values they should be the same (+/- rounding error).

How to draw horizontal line from yesterdays high and close points? and how to solve time format? Fill between lines

I'm new here and i want to ask about my work. So I'm using this code for now but result is shown only full horizontal line not from the high from highestbars . How can i draw from exact highest price?
And im using time.session like "0000-0500" but this session in 1 exchange (broker)is different from other
exchanges. So how can I use same Session?
high = security(syminfo.tickerid, 'D', time[1], lookahead = barmerge.lookahead_on)
prevhigh = security(syminfo.tickerid, 'D', high[1], lookahead = barmerge.lookahead_on)
var high_line = line.new(x1 = high, x2 = right(extend_right), y1 = prevhigh, y2 = prevhigh, color = line_color, width = line_width, xloc = xloc.bar_time)
line.set_x1(high_line, high)
And can i fill between 2 lines which drawn by above code?
i used Line.set
Thank you.

Reflecting boundary conditions in FiPy

I am attempting to solve the convection diffusion equation in FiPy. For the moment, all I am trying to achieve is a Neumann boundary condition, so that the wave reflects back at the right-hand boundary rather than travelling out of the domain.
I have added the following line:
phi.faceGrad.constrain(0, mesh.exteriorFaces)
But this doesn't seem to change anything.
Am I imposing the wrong boundary condition? Am I imposing it incorrectly? I have searched for this, but can't seem to find an example which has the simple property of a wave reflecting off a boundary! My code is below. Thanks so much.
from fipy import *
nx = 100
L = 1.
dx = L/nx
steps = 160
dt = 0.1
t = dt * steps
mesh = Grid1D(nx=nx, dx=dx)
x = mesh.cellCenters[0]
phi = CellVariable(name="solution variable", mesh=mesh, value=0.)
phi.setValue(1., where=(x>0.03) & (x<0.09))
# Diffusion and convection coefficients
D = FaceVariable(name='diffusion coefficient',mesh=mesh,value=1.*10**(-4.))
C = (0.1,)
# Boundary conditions
phi.faceGrad.constrain(0, mesh.exteriorFaces)
eq = TransientTerm() == DiffusionTerm(coeff=D) - ConvectionTerm(coeff=C)
for step in range(steps):
eq.solve(var=phi, dt=dt)
if step%20==0:
viewer = Viewer(vars=phi, datamin=0., datamax=1.)
viewer.plot()