I need to generate a double 3D gyroid structure. For this, I'm using vedo
from matplotlib import pyplot as plt
from scipy.constants import speed_of_light
from vedo import *
import numpy as np
# Paramters
a = 5
length = 100
width = 100
height = 10
pi = np.pi
x, y, z = np.mgrid[:length, :width, :height]
def gen_strut(start, stop):
'''Generate the strut parameter t for the gyroid surface. Create a linear gradient'''
strut_param = np.ones((length, 1))
strut_param = strut_param * np.linspace(start, stop, width)
t = np.repeat(strut_param[:, :, np.newaxis], height, axis=2)
return t
plt = Plotter(shape=(1, 1), interactive=False, axes=3)
scale=0.5
cox = cos(scale * pi * x / a)
siy = sin(scale * pi * y / a)
coy = cos(scale * pi * y / a)
siz = sin(scale * pi * z / a)
coz = cos(scale * pi * z / a)
six = sin(scale * pi * x / a)
U1 = ((six ** 2) * (coy ** 2) +
(siy ** 2) * (coz ** 2) +
(siz ** 2) * (cox ** 2) +
(2 * six * coy * siy * coz) +
(2 * six * coy * siz * cox) +
(2 * cox * siy * siz * coz)) - (gen_strut(0, 1.3) ** 2)
threshold = 0
iso1 = Volume(U1).isosurface(threshold).c('silver').alpha(1)
cube = TessellatedBox(n=(int(length-1), int(width-1), int(height-1)), spacing=(1, 1, 1))
iso_cut = cube.cutWithMesh(iso1).c('silver').alpha(1)
# Combine the two meshes into a single mesh
plt.at(0).show([cube, iso1], "Double Gyroid 1", resetcam=False)
plt.interactive().close()
The result looks quite good, but now I'm struggling with exporting the volume. Although vedo has over 300 examples, I did not find anything in the documentation to export this as a watertight volume for 3D-Printing. How can I achieve this?
I assume you mean that you want to extract a watertight mesh as an STL (?).
This is a non trivial problem because it is only well defined on a subset of the mesh regions where the in/out is not ambiguous, in those cases fill_holes() seems to do a decent job..
Other cases should be dealt "manually". Eg, you can access the boundaries with mesh.boundaries() and try to snap the vertices to a closest common vertex. This script is not a solution, but I hope can give some ideas on how to proceed.
from vedo import *
# Paramters
a = 5
length = 100
width = 100
height = 10
def gen_strut(start, stop):
strut_param = np.ones((length, 1))
strut_param = strut_param * np.linspace(start, stop, width)
t = np.repeat(strut_param[:, :, np.newaxis], height, axis=2)
return t
scale=0.5
pi = np.pi
x, y, z = np.mgrid[:length, :width, :height]
cox = cos(scale * pi * x / a)
siy = sin(scale * pi * y / a)
coy = cos(scale * pi * y / a)
siz = sin(scale * pi * z / a)
coz = cos(scale * pi * z / a)
six = sin(scale * pi * x / a)
U1 = ((six ** 2) * (coy ** 2) +
(siy ** 2) * (coz ** 2) +
(siz ** 2) * (cox ** 2) +
(2 * six * coy * siy * coz) +
(2 * six * coy * siz * cox) +
(2 * cox * siy * siz * coz)) - (gen_strut(0, 1.3) ** 2)
iso = Volume(U1).isosurface(0).c('silver').backcolor("p5").lw(1).flat()
cube = TessellatedBox(n=(length-1, width-1, height-1)).c('red5').alpha(1)
cube.triangulate().compute_normals()
cube.cut_with_mesh(iso).compute_normals()
print(iso.boundaries(return_point_ids=True))
print(cube.boundaries(return_point_ids=True))
print(iso.boundaries().join().lines())
show(iso, cube).close()
merge(iso, cube).clean().backcolor("p5").show().close()
iso.clone().fill_holes(15).backcolor("p5").show().close()
So I am looking to solve a system of equations in python 3.7 with numpy. However, I need to solve the system of equations at the end of each iteration. During the iterations, it will solve some equations that will make up the contents of A and B to find x in the form of Ax=B. Upon solving for x I need to save these values to then solve the underlying equations for the following iteration to be reimplemented in A and B.
I have tried a more linear approach to solving the problem but it is not good for my end goal of solving the equation attached in the image. What I have done so far has also been attached below:
i = 0
while (y[i] >= 0 ): #Object is above water
t[i+1] = t[i] + dt
vx[i+1] = vx[i] + dt * ax[i] #Update the velocities
vy[i+1] = vy[i] + dt * ay[i]
v_ax[i+1] = (vx[i]*np.sin(phi/180*np.pi)) - (vy[i]*np.cos(phi/180*np.pi))
v_nor[i+1] = (vx[i]*np.cos(phi/180*np.pi)) + (vy[i]*np.sin(phi/180*np.pi))
F_wnor[i+1] = (Cd_a * A_da * rho_air * (v_nor[i] - v_wind*np.sin(phi/180*np.pi)) * abs(v_nor[i] - v_wind*np.sin(phi/180*np.pi)))/2
F_wax[i+1] = (Cd_a * A_da * rho_air * (v_ax[i] - v_wind*np.sin(phi/180*np.pi)) * abs(v_ax[i] - v_wind*np.sin(phi/180*np.pi)))/2
F_wx[i+1] = (-F_wax[i] * np.sin(phi/180*np.pi)) - (F_wnor[i] * np.cos(phi/180*np.pi))
F_wy[i+1] = (F_wax[i] * np.cos(phi/180*np.pi)) - (F_wnor[i] * np.sin(phi/180*np.pi))
ax[i+1] = F_wx[i]/M
ay[i+1] = (F_wx[i]/M) - g
y[i+1] = (y[i]+dt*vy[i])
x[i+1] = (x[i]+dt*vx[i])
i = i + 1
j = i
#under water velocities
# if y(t)>0: M*z'' = M.g - Fb + Fd + Fm
while (y[j] <= 0 and y[j] > -10):
if (abs(y[j]/r)< 2):
theta_degree = 2 * np.arccos(1 - (abs(y[j])/r))
theta = theta_degree/180*np.pi
m = ((rho_water * r**2)/2) * (((2*(np.pi)**3*(1-np.cos(theta))) / ( 3 * (2*np.pi-theta)**2)) \
+ (np.pi * (1-np.cos(theta)*1/3)) + (np.sin(theta)) - (theta))
dm_dz = ((rho_water * r)/np.sin(theta/2)) * (((2 * (np.pi)**3 / 3) * ((np.sin(theta) / (2*np.pi - theta)**2) \
+ (2 * (1-np.cos(theta)) / (2*np.pi - theta )**3))) + (np.pi * np.sin(theta) / 3) + np.cos(theta) - 1)
A_i = (r**2)/2 * (theta - np.sin(theta))
F_m[j] = - m * ay[j] - dm_dz * np.max(vy)*vy[j]
F_uwater[j] = (M * g) - (rho_water * A_i * g) - (Cd_y * rho_water * r * vy[j] * abs(vy[j]))
else:
m = np.pi * rho_water * r**2
dm_dz = 0
A_i = np.pi * r**2
F_m[j] = - m * ay[j] - dm_dz * vy[j]**2
F_uwater[j] = (M * g) - (rho_water * A_i * g) - (Cd_y * rho_water * r * vy[j] * abs(vy[j]))
print("Fully submerged")
t[j+1] = t[j] + dt
vx[j+1] = vx[j] + dt * ax[j] #Update the velocities
vy[j+1] = vy[j] + dt * ay[j]
ax[j+1] = F_wx[j]/M
ay[j+1] = (F_uwater[j] + F_m[j]/M)
y[j+1] = (y[j]+dt*vy[j])
x[j+1] = (x[j]+dt*vx[j])
print(y[j])
j = j + 1
I do not know how to go about this and help for getting started would be greatly appreciated!.
The problem I am trying to solve can be seen more clearly in the picture attached. System of equations I am trying to solve
I've got some XYZ coordinates in Kilometers (gotten using wgs) with the origin at the center of the Earth, is it possible to convert this into latitude and longitude?
In addition: how can I do this quickly inside python?
It's simply a reverse of this question here: Converting from longitude\latitude to Cartesian coordinates
Based on #daphshez answer
You can use this code,
Here, x, y and z are in Kms and R is an approximate diameter of Earth.
import numpy as np
R = 6371
lat = np.degrees(np.arcsin(z/R))
lon = np.degrees(np.arctan2(y, x))
This is how you do it. Taking into account both radiuses. Based on:
https://gist.github.com/govert/1b373696c9a27ff4c72a
and verifyed.
import math
x = float(4333216) #in meters
y = float(3193635) #in meters
z = float(3375365) #in meters
a = 6378137.0 #in meters
b = 6356752.314245 #in meters
f = (a - b) / a
f_inv = 1.0 / f
e_sq = f * (2 - f)
eps = e_sq / (1.0 - e_sq)
p = math.sqrt(x * x + y * y)
q = math.atan2((z * a), (p * b))
sin_q = math.sin(q)
cos_q = math.cos(q)
sin_q_3 = sin_q * sin_q * sin_q
cos_q_3 = cos_q * cos_q * cos_q
phi = math.atan2((z + eps * b * sin_q_3), (p - e_sq * a * cos_q_3))
lam = math.atan2(y, x)
v = a / math.sqrt(1.0 - e_sq * math.sin(phi) * math.sin(phi))
h = (p / math.cos(phi)) - v
lat = math.degrees(phi)
lon = math.degrees(lam)
print(lat,lon,h)
I have stiff system of differential equations given to the first-order ODE. This system is written in Maple. The default method used by Maple is the Rosenbrock method. Now my task is to solve these equations with python tools.
1) I do not know how to write the equations in the python code.
2) I do not know how to solve the equations with numpy, scipy, matplotlib or PyDSTool. For the library PyDSTool I did not find any examples at all, although I read that it is well suited for stiff systems.
Code:
import numpy
import scipy
import matplotlib
varepsilon = pow(10, -2); j = -2.5*pow(10, -2); e = 3.0; tau = 0.3; delta = 2.0
u0 = -math.sqrt(-1 + math.sqrt(varepsilon ** 2 + 12) / varepsilon) * math.sqrt(2) / 6
u = -math.sqrt(-1 + math.sqrt(varepsilon ** 2 + 12) / varepsilon) * math.sqrt(2) * (1 + delta) / 6
v = 1 / (1 - 2 / e) * math.sqrt(j ** 2 + (1 - 2 / e) * (e ** 2 * u ** 2 + 1))
y8 = lambda y1,y5,y7: 1 / (1 - 2 / y1) * math.sqrt(y5 ** 2 + (1 - 2 / y1) * (1 + y1 ** 2 * y7 ** 2))
E0 = lambda y1,y8: (1 - 2 / y1) * y8
Phi0 = lambda y1,y7: y1 ** 2 * y7
y08 = y8(y1=e, y5=j, y7=u0);
E = E0(y1=e, y8=y08); Phi = Phi0(y1=e, y7=u0)
# initial values
z01 = e; z03 = 0; z04 = 0; z05 = j; z07 = u0; z08 = y08;
p1 = -z1(x)*z5(x)/(z1(x)-2);
p3 = -z1(x)^2*z7(x);
p4 = z8(x)*(1-2/z1(x));
Q1 = -z5(x)^2/(z1(x)*(z1(x)-2))+(z8(x)^2/z1(x)^3-z7(x)^2)*(z1(x)-2);
Q3 = 2*z5(x)*z7(x)/z1(x);
Q4 = 2*z5(x)*z8(x)/(z1(x)*(z1(x)-2));
c1 = z1(x)*z7(x)*varepsilon;
c3 = -z1(x)*z5(x)*varepsilon;
C = z7(x)*varepsilon/z1(x)-z8(x)*(1-2/z1(x));
d1 = -z1(x)*z8(x)*varepsilon;
d3 = z1(x)*z5(x)*varepsilon;
B = z1(x)^2*z7(x)-z8(x)*varepsilon*(1-2/z1(x));
Omega = 1/(c1*d3*p3+c3*d1*p4-c3*d3*p1);
# differential equations
diff(z1(x), x) = z5(x);
diff(z3(x), x) = z7(x);
diff(z4(x), x) = z8(x);
diff(z5(x), x) = Omega*(-Q1*c1*d3*p3 - Q1*c3*d1*p4 + Q1*c3*d3*p1 + B*c3*p4 + C*d3*p3 + E*d3*p3 - Phi*c3*p4);
diff(z7(x), x) = -Omega*(Q3*c1*d3*p3 + Q3*c3*d1*p4 - Q3*c3*d3*p1 + B*c1*p4 - C*d1*p4 + C*d3*p1 - E*d1*p4 + E*d3*p1 - Phi*c1*p4);
diff(z8(x), x) = Omega*(-Q4*c1*d3*p3 - Q4*c3*d1*p4 + Q4*c3*d3*p1 + B*c1*p3 - B*c3*p1 - C*d1*p3 - E*d1*p3 - Phi*c1*p3 + Phi*c3*p1);
#features to be found and built curve
{z1(x), z3(x), z4(x), z5(x), z7(x), z8(x)}
After drifting on the Internet, I found something in principle:
import math
import matplotlib.pyplot as plt
import numpy as np
from scipy import integrate
from scipy.signal import argrelextrema
from mpmath import mp, mpf
mp.dps = 50
varepsilon = pow(10, -2); j = 2.5*pow(10, -4); e = 3.0; tau = 0.5; delta = 2.0
u0 = -math.sqrt(-1 + math.sqrt(varepsilon ** 2 + 12) / varepsilon) * math.sqrt(2) / 6
u = -math.sqrt(-1 + math.sqrt(varepsilon ** 2 + 12) / varepsilon) * math.sqrt(2) * (1 + delta) / 6
v = 1 / (1 - 2 / e) * math.sqrt(j ** 2 + (1 - 2 / e) * (e ** 2 * u ** 2 + 1))
y8 = lambda y1,y5,y7: 1 / (1 - 2 / y1) * math.sqrt(y5 ** 2 + (1 - 2 / y1) * (1 + y1 ** 2 * y7 ** 2))
E0 = lambda y1,y8: (1 - 2 / y1) * y8
Phi0 = lambda y1,y7: y1 ** 2 * y7
y08 = y8(y1=e, y5=j, y7=u0);
E = E0(y1=e, y8=y08); Phi = Phi0(y1=e, y7=u0)
# initial values
z01 = e; z03 = 0.0; z04 = 0.0; z05 = j; z07 = u0; z08 = y08;
def model(x, z, varepsilon, E, Phi):
z1, z3, z4, z5, z7, z8 = z[0], z[1], z[2], z[3], z[4], z[5]
p1 = -z1*z5/(z1 - 2);
p3 = -pow(z1, 2) *z7;
p4 = z8*(1 - 2/z1);
Q1 = -pow(z5, 2)/(z1*(z1 - 2)) + (pow(z8, 2)/pow(z1, 3) - pow(z7, 2))*(z1 - 2);
Q3 = 2*z5*z7/z1;
Q4 = 2*z5*z8/(z1*(z1 - 2));
c1 = z1*z7*varepsilon;
c3 = -z1*z5*varepsilon;
C = z7*varepsilon/z1 - z8*(1 - 2/z1);
d1 = -z1*z8*varepsilon;
d3 = z1*z5*varepsilon;
B = pow(z1, 2)*z7 - z8*varepsilon*(1 - 2/z1);
Omega = 1/(c1*d3*p3+c3*d1*p4-c3*d3*p1);
# differential equations
dz1dx = z5;
dz3dx = z7;
dz4dx = z8;
dz5dx = Omega*(-Q1*c1*d3*p3 - Q1*c3*d1*p4 + Q1*c3*d3*p1 + B*c3*p4 + C*d3*p3 + E*d3*p3 - Phi*c3*p4);
dz7dx = -Omega*(Q3*c1*d3*p3 + Q3*c3*d1*p4 - Q3*c3*d3*p1 + B*c1*p4 - C*d1*p4 + C*d3*p1 - E*d1*p4 + E*d3*p1 - Phi*c1*p4);
dz8dx = Omega*(-Q4*c1*d3*p3 - Q4*c3*d1*p4 + Q4*c3*d3*p1 + B*c1*p3 - B*c3*p1 - C*d1*p3 - E*d1*p3 - Phi*c1*p3 + Phi*c3*p1);
dzdx = [dz1dx, dz3dx, dz4dx, dz5dx, dz7dx, dz8dx]
return dzdx
z0 = [z01, z03, z04, z05, z07, z08]
if __name__ == '__main__':
# Start by specifying the integrator:
# use ``vode`` with "backward differentiation formula"
r = integrate.ode(model).set_integrator('vode', method='bdf')
r.set_f_params(varepsilon, E, Phi)
# Set the time range
t_start = 0.0
t_final = 0.1
delta_t = 0.00001
# Number of time steps: 1 extra for initial condition
num_steps = np.floor((t_final - t_start)/delta_t) + 1
r.set_initial_value(z0, t_start)
t = np.zeros((int(num_steps), 1), dtype=np.float64)
Z = np.zeros((int(num_steps), 6,), dtype=np.float64)
t[0] = t_start
Z[0] = z0
k = 1
while r.successful() and k < num_steps:
r.integrate(r.t + delta_t)
# Store the results to plot later
t[k] = r.t
Z[k] = r.y
k += 1
# All done! Plot the trajectories:
Z1, Z3, Z4, Z5, Z7, Z8 = Z[:,0], Z[:,1] ,Z[:,2], Z[:,3], Z[:,4], Z[:,5]
plt.plot(t,Z1,'r-',label=r'$r(s)$')
plt.grid('on')
plt.ylabel(r'$r$')
plt.xlabel('proper time s')
plt.legend(loc='best')
plt.show()
plt.plot(t,Z5,'r-',label=r'$\frac{dr}{ds}$')
plt.grid('on')
plt.ylabel(r'$\frac{dr}{ds}$')
plt.xlabel('proper time s')
plt.legend(loc='best')
plt.show()
plt.plot(t, Z7, 'r-', label=r'$\frac{dϕ}{ds}$')
plt.grid('on')
plt.xlabel('proper time s')
plt.ylabel(r'$\frac{dϕ}{ds}$')
plt.legend(loc='upper center')
plt.show()
However, reviewing the solutions obtained by the library scipy,
I encountered the problem of inconsistency of the solutions obtained by scipy and Maple. The essence of the problem is that the solutions are quickly oscillating and the Maple catches these oscillations with high precision using Rosenbrock's method. While Pythonn has problems with this using Backward Differentiation Methods:
r = integrate.ode(model).set_integrator('vode', method='bdf')
http://www.scholarpedia.org/article/Backward_differentiation_formulas
I tried all the modes of integrating: “vode” ; “zvode”; “lsoda” ; “dopri5” ; “dop853” and I found that the best suited mode “vode” however, still does not meet my needs...
https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.ode.html
So this method catches oscillations in the range j ~ 10^{-5}-10^{-3}..While the maple shows good results for any j.
I present the results obtained by scipy for j ~ 10^{-2}:
enter image description here
enter image description here
and the results obtained by Maple for j ~ 10^{-2}:
enter image description here
enter image description here
It is important that oscillations are physical solutions! That is, the Python badly captures oscillations for j ~ 10^{-2}((. Can anyone tell me what I'm doing wrong?? how to look at the absolute error of integration?
I need to convert tiles number into lon./lag in EPSG:3395 but i don't find the solution.
I've found the code for EPSG:4326 but i don't find a way to adapt it for EPSG:3395.
Code for 4326 (it works well) :
$n = pow(2, $zoom);
$lon_deg = $xtile / $n * 360.0 - 180.0;
$lat_deg = rad2deg(atan(sinh(pi() * (1 - 2 * $ytile / $n))));
I need to convert tiles number into lon./lag in EPSG:3395 but i don't find a working solution. I have implemented some code based on this answer.
when I've tried to convert 4326 degrees into 3395 degrees:
def getVal(x, y, n):
lon_deg = x / n * 360.0 - 180.0
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * y / n)))
lat_deg = math.degrees(lat_rad)
#Convert in 3395
a = 6378137 #WGS84 semi-major axis
b = 6356752.3142 #WGS84 semi-minor axis
print(math.sqrt(1 - b^2 / a^2))
e = math.sqrt(1 - b^2 / a^2) #ellipsoid eccentricity
c = math.pow((1 - e*math.sin(latitude)) / (1 + e*math.sin(latitude)), e/2)
lat_deg = a * ln(math.tan(math.pi/4 + lat_deg/2) * c)
lon_deg = a * lon_deg;
I obtain the following Error message:
Unsupported operand type(s) for float and INT
Update: I have corrected to code to below by replacing ^ with **.
Code:
def getVal(x, y, n):
#Calcuate coordinates in 4326
lon_deg = x / n * 360.0 - 180.0
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * y / n)))
lat_deg = math.degrees(lat_rad)
#Convert coordinates in 3395
a = 6378137 #WGS84 semi-major axis
b = 6356752.3142 #WGS84 semi-minor axis
e = math.sqrt(1 - b**2 / a**2) #ellipsoid eccentricity
c = math.pow((1 - e*math.sin(lat_deg)) / (1 + e*math.sin(lat_deg)), e/2)
lon_deg = a * lon_deg;
lat_deg = a * math.log(math.tan(math.radians(math.pi/4 + lat_deg/2) * c))
But still the projection is strange.
I assume the problem is on this part:
lat_deg = a * math.log(math.tan(math.radians(math.pi/4 + lat_deg/2)
I had to insert math.radians as math.tan doesn't like degree angle.
Any idea?
Looks like you want to know the formulae to convert coordinates to EPSG:3395. I dont know if this is the right place for this question, but this might help.
When trying to raise to a power use the operand ** not ^.
def getVal(x, y, n):
lon_deg = x / n * 360.0 - 180.0
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * y / n)))
lat_deg = math.degrees(lat_rad)
#Convert in 3395
a = 6378137 #WGS84 semi-major axis
b = 6356752.3142 #WGS84 semi-minor axis
print(math.sqrt(1 - b**2 / a**2))
e = math.sqrt(1 - b**2 / a**2) #ellipsoid eccentricity
c = math.pow((1 - e*math.sin(latitude)) / (1 + e*math.sin(latitude)), e/2)
lat_deg = a * ln(math.tan(math.pi/4 + lat_deg/2) * c)
lon_deg = a * lon_deg;