Asking advice on optimizing a while loop - python

This is part of an algorithm regarding the RKF method
t = self.a
x = np.array(self.x0)
h = self.hmax
T = np.array( [t] )
X = np.array( [x] )
k= [0]*6
while t < self.b:
if t + h > self.b:
h = self.b - t
k[0] = h * self.f(t, x)
k[1] = h * self.f(t + a2 * h, x + b21 * k[0] )
k[2] = h * self.f(t + a3 * h, x + b31 * k[0] + b32 * k[1])
k[3] = h * self.f(t + a4 * h, x + b41 * k[0] + b42 * k[1] + b43 * k[2])
k[4] = h * self.f(t + a5 * h, x + b51 * k[0] + b52 * k[1] + b53 * k[2] + b54 * k[3])
k[5] = h * self.f(t + a6 * h, x + b61 * k[0] + b62 * k[1] + b63 * k[2] + b64 * k[3] + b65 * k[4])
r = abs( r1 * k[0] + r3 * k[2] + r4 * k[3] + r5 * k[4] + r6 * k[5] ) / h
r = r / (self.atol+self.rtol*(abs(x)+abs(k[0])))
if len( np.shape( r ) ) > 0:
r = max( r )
if r <= 1:
t = t + h
x = x + c1 * k[0] + c3 * k[2] + c4 * k[3] + c5 * k[4]
T = np.append( T, t )
X = np.append( X, [x], 0 )
h = h * min( max( 0.94 * sqrt(sqrt( 1 / r )), 0.1 ), 4.0 )
if h > self.hmax:
h = self.hmax
elif h < self.hmin or t==t-h:
raise RuntimeError("Error: Could not converge to the required tolerance.")
break
Which works just fine, but I was wondering if is it possible to make this even faster and more efficient?

Related

Cant exit while loop on Simpson's Rule

I am trying to calculate an integral using Simpson's Rule formula.The catch is that the value of the integral is the one that satisfies the following condition:You find the Ih and Ih/2.If the absolute of (Ih-Ih/2)<error the loop is complete.Otherwise you repeat the process with half the h,which means it calculates the absolute of (Ih/2-Ih/4) and so on and so on.
while True:
###Ih part
h = (b - a) / N
y1 = np.linspace(a, b, N)
Ez11 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
I11 = (h/3) * (Ez11[0] + 2*sum(Ez11[:N-2:2]) \
+ 4*sum(Ez11[1:N-1:2]) + Ez11[N-1])
#####Ih/2 part
h = (b-a)/(2*N)
y2 = np.linspace(a, b, 2*N)
Ez22 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
print(Ez22)
I22 = (h/ 3) * (Ez22[0] + 2 * sum(Ez22[:N - 2:2]) \
+ 4 * sum(Ez22[1:N - 1:2]) + Ez22[N - 1])
# error condition I1=Ih I2=Ih/2
if np.abs(I11 - I22) < error:
break
else:
N = 2*N # h/2
print(np.abs(I11 - I22))
As far as I can tell,my approach should be correct.However the loop goes on and on,never to stop.
My code is as follows:
import numpy as np
from scipy.integrate import simps
import scipy.integrate as integrate
import scipy.special as special
# variables
a = 0
b = np.pi * 2
N = 100
ra = 0.1 # ρα
R = 0.05
fa = 35 * (np.pi / 180) # φα
za = 0.4
Q = 10 ** (-6)
k = 9 * 10 ** 9
aa = np.sqrt(ra ** 2 + R ** 2 + za ** 2)
error = 0.55 * 10 ** (-8)
h=(b-a)/N
I1 = np.nan
I11 = np.nan
#Simpsons section
############ Ez
#automated Simpson
while True:
###Ih part
y1 = np.linspace(a, b, N)
Ez1 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
print(len(Ez1))
I1 = simps(Ez1, y1)
#####Ih/2 part
y2 = np.linspace(a, b, 2*N)
Ez2 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
I2 = simps(Ez2, y2)
# error condition I1=Ih I2=Ih/2
if np.abs(I1 - I2) < error:
break
else:
N *= 2 # h/2
#custom-made Simpson
N = 100
while True:
###Ih part
h = (b - a) / N
y1 = np.linspace(a, b, N)
Ez11 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y1 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y1 - fa)) ** (3 / 2))
I11 = (h/3) * (Ez11[0] + 2*sum(Ez11[:N-2:2]) \
+ 4*sum(Ez11[1:N-1:2]) + Ez11[N-1])
#####Ih/2 part
h = (b-a)/(2*N)
y2 = np.linspace(a, b, 2*N)
Ez22 = (np.sqrt(ra ** 2 + R ** 2 - 2 * ra * R * np.cos(y2 - fa))) / (
(aa ** 2 - 2 * ra * R * np.cos(y2 - fa)) ** (3 / 2))
print(Ez22)
I22 = (h/ 3) * (Ez22[0] + 2 * sum(Ez22[:N - 2:2]) \
+ 4 * sum(Ez22[1:N - 1:2]) + Ez22[N - 1])
# error condition I1=Ih I2=Ih/2
if np.abs(I11 - I22) < error:
break
else:
N = 2*N # h/2
print(np.abs(I11 - I22))
print(I1)
print(I11)
Simpson's Rule is as follows:
After a while it's stuck in this situation
The 5.23 part is the absolute diff of those 2 which shouldnt be that high.

solving coupled differential equations with a periodically changing constant in the function with python

I am solving a system of coupled differential equations, with one of the "constant" in the differential equations is actually a periodically changing value: first half of the period has the value of 1 and the rest of the period have the value of 0, and the period is 2pi.
import matplotlib.pyplot as plt
import numpy as np
import math
l=1
lt=0
k=0.05
eps= 0.11
w= (1 - eps)
w_0= (1 + eps)
u=(w_0/4*w)*(w**2+(k/2)**2)
def RungeKutta(t, jx, jy, jz, x, p, dt, djxdt, djydt, djzdt, dxdt, dpdt):
a1 = dt * djxdt(t, jx, jy, jz, x, p)
b1 = dt * djydt(t, jx, jy, jz, x, p)
c1 = dt * djzdt(t, jx, jy, jz, x, p)
d1 = dt * dxdt(t, jx, jy, jz, x, p)
e1 = dt * dpdt(t, jx, jy, jz, x, p)
a2 = dt * djxdt(t + 0.5 * dt, jx + 0.5 * a1, jy + 0.5 * b1, jz + 0.5 * c1, x + 0.5 * d1, p + 0.5 * e1)
b2 = dt * djydt(t + 0.5 * dt, jx + 0.5 * a1, jy + 0.5 * b1, jz + 0.5 * c1, x + 0.5 * d1, p + 0.5 * e1)
c2 = dt * djzdt(t0 + 0.5 * dt, jx + 0.5 * a1, jy + 0.5 * b1, jz + 0.5 * c1, x + 0.5 * d1, p + 0.5 * e1)
d2 = dt * dxdt(t0 + 0.5 * dt, jx + 0.5 * a1, jy + 0.5 * b1, jz + 0.5 * c1, x + 0.5 * d1, p + 0.5 * e1)
e2 = dt * dpdt(t0 + 0.5 * dt, jx + 0.5 * a1, jy + 0.5 * b1, jz + 0.5 * c1, x + 0.5 * d1, p + 0.5 * e1)
a3 = dt * djxdt(t + 0.5 * dt, jx + 0.5 * a2, jy + 0.5 * b2, jz + 0.5 * c2, x + 0.5 * d2, p + 0.5 * e2)
b3 = dt * djydt(t + 0.5 * dt, jx + 0.5 * a2, jy + 0.5 * b2, jz + 0.5 * c2, x + 0.5 * d2, p + 0.5 * e2)
c3 = dt * djzdt(t + 0.5 * dt, jx + 0.5 * a2, jy + 0.5 * b2, jz + 0.5 * c2, x + 0.5 * d2, p + 0.5 * e2)
d3 = dt * dxdt(t + 0.5 * dt, jx + 0.5 * a2, jy + 0.5 * b2, jz + 0.5 * c2, x + 0.5 * d2, p + 0.5 * e2)
e3 = dt * dpdt(t + 0.5 * dt, jx + 0.5 * a2, jy + 0.5 * b2, jz + 0.5 * c2, x + 0.5 * d2, p + 0.5 * e2)
a4 = dt * djxdt(t + dt, jx + a3, jy + b3, jz + c3, x + d3, p + e3)
b4 = dt * djydt(t + dt, jx + a3, jy + b3, jz + c3, x + d3, p + e3)
c4 = dt * djzdt(t + dt, jx + a3, jy + b3, jz + c3, x + d3, p + e3)
d4 = dt * dxdt(t + dt, jx + a3, jy + b3, jz + c3, x + d3, p + e3)
e4 = dt * dpdt(t + dt, jx + a3, jy + b3, jz + c3, x + d3, p + e3)
t = t+dt
jx = jx+(1/6)*(a1+2*a2+2*a3+a4)
jy = jy+(1/6)*(b1+2*b2+2*b3+b4)
jz = jz+(1/6)*(c1+2*c2+2*c3+c4)
x = x+(1/6)*(d1+2*d2+2*d3+d4)
p = p+(1/6)*(e1+2*e2+2*e3+e4)
return t, jx, jy, jz, x, p
def djxdt(t, jx, jy, jz, x, p):
return -w_0*jy
def djydt(t, jx, jy, jz, x, p):
return w_0*jx-2*lambda_t(t)*(math.sqrt(2*w))*x*jz
def djzdt(t, jx, jy, jz, x, p):
return 2*lambda_t(t)*(math.sqrt(2*w))*x*jy
def dxdt(t, jx, jy, jz, x, p):
return p-(k/2)*x
def dpdt(t, jx, jy, jz, x, p):
return -(w**2)*x-(k/2)*p-2*lambda_t(t)*(math.sqrt(2*w))*jx
def lambda_t(t):
if math.fmod(t, 2*np.pi) > np.pi:
return 1
else:
return 0
t0=0
jx0= 0.5*math.sqrt(1-u**2)
jy0= 0
jz0= -0.5*u
x0= -math.sqrt(2*w*(1-u**2))/(w**2-(k**2)/4)
p0= -(k/2)*math.sqrt(2*w*(1-u**2))/(w**2-(k**2)/4)
dt=0.0001*2*np.pi
t_end=50
t_list = [t0]
jx_list = [jx0]
jy_list = [jy0]
jz_list = [jz0]
x_list = [x0]
p_list = [p0]
t_list2 = [t0]
jx_list2 = [jx0]
t = t0
jx=jx0
jy=jy0
jz=jx0
x=x0
p=p0
while t <= t_end:
t, jx, jy, jz, x, p = RungeKutta(t, jx, jy, jz, x, p, dt, djxdt, djydt, djzdt, dxdt, dpdt)
if (t%2*math.pi<0.000001 or t%2*math.pi>0.000001):
t_list2.append(t)
jx_list2.append(jx)
t_list.append(t)
jx_list.append(jx)
jy_list.append(jy)
jz_list.append(jz)
x_list.append(x)
p_list.append(p)
plt.plot(t_list, jx_list, label="Jx")
plt.plot(t_list, jy_list, label="Jy")
plt.plot(t_list, jz_list, label="Jz")
plt.legend(fontsize=15)
plt.show()
plt.scatter(t_list2, jx_list2)
plt.show()
I do not know why it always comes out the error of unindent does not match any outer indentation level.
Also I need to plot the point and value only when t is the multiple of 2pi. I tried the code for
if (t%2*math.pi==0):
t_list2.append(t)
jx_list2.append(jx)
But the figure comes out with only a dot at t=0
How to fix this problem? Is my previous setting influencing this part?
Thanks for any help!
There are several things wrong from a pure python perspective in this function
def l(f):
if int(2*t)%2np.pi == 0:
return 1
else:
return -1
The parameter f is not used in the function, instead an undeclared t appears.
2np.pi should give an immediate syntactic error
int(2*t)%2*np.pi is(int(2*t)%2)*np.pi, which is likely not the desired interpretation. Use int((2*f)%(2*np.pi)). You can also cancel the 2
The lower value is -1, while in the description you have 0.
model is a system for 3 state components, your initial state has 5 components. That is not compatible.
Repeating expressions should be assigned to a local variable to avoid redundant computation.
Please report a detailed error description, not just your summary of the observed error.

'IndexError: index 4 is out of bounds for axis 1 with size 4'

I'm doing this code but I have a problem in the line 40, with a Index Error. I don't know if there is a problem with the nr-1, inside the for.
The code:
import numpy
Z = 1
R = 1
nr = 5
nz = 4
kn = 1
ks = 1
ke = 1
kw = 1
T = numpy.zeros((nr, nz), dtype=float)
vetorq = 1
for a in range(1, 100, 1):
for i in range(0, nz, 1):
for j in range(0, nr, 1):
an = (i + (1 / 2)) * (R ** 2)*nz*kn/ ((nr**2)* Z)
ae = (i + 2) * Z*ke / nz
aw = ((i+1)*kw * Z) / nz
asul = (i + (1 / 2)) * (R ** 2)*nz*ks / (Z * (nr**2))
ap = an + ae + aw + asul
aef = 0
if (i == 0 and j == 0):
T[i, j] = ae * ((T[i, j + 1]) / ap) + asul * (
(T[i + 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i + 1/2) / ((nr ** 2) * nz * ap) + aef / ap
elif(i == 0 and j != 0 and j != nr - 1):
T[i, j] = ae * ((T[i, j + 1]) / ap) + aw * ((T[i, j - 1]) / ap) + asul * (
(T[i + 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i + 1/2) / ((nr ** 2) * nz * ap) + aef / ap
elif(i == 0 and j == nr - 1):
aef = (i + 2) * R * Z * vetorq / (nr * nz)
T[i, j] = aw * ((T[i, j - 1]) / ap) + asul * (
(T[i + 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i + 1/2) / ((nr ** 2) * nz * ap) + aef / ap
elif(i != 0 and i != nz - 1 and j == nr - 1):
aef = (i + 2) * R * Z * vetorq / (nr * nz)
T[i, j] = aw * ((T[i, j - 1]) / ap) + an * ((T[i - 1, j]) / ap) + asul * (
(T[i + 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i + 1/2) / ((nr ** 2) * nz * ap) + aef / ap
elif(i == nz - 1 and j == nr - 1):
aef = (i + 2) * R * Z * vetorq / (nr * nz)
T[i, j] = aw * ((T[i, j - 1]) / ap) + an * ((T[i - 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i + 1/2) /((nr ** 2) * nz * ap) + aef / ap
elif(i == nz - 1 and j != 0 and j != nr - 1):
T[i, j] = ae * ((T[i, j + 1]) / ap) + aw * ((T[i, j - 1]) / ap) + an * ((T[i - 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i + 1/2) / ((nr ** 2) * nz * ap) + aef / ap
elif(i == nz - 1 and j == 0):
T[i, j] = ae * ((T[i, j + 1]) / ap) + an * ((T[i - 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i + 1/2) / ((nr ** 2) * nz * ap) + aef / ap
elif(i != 0 and i != nz - 1 and j == 0):
T[i, j] = ae * ((T[i, j + 1]) / ap) + an * ((T[i - 1, j]) / ap) + asul * (
(T[i + 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i + 1/2) / ((nr ** 2) * nz * ap) + aef / ap
elif(i != 0 and i != nz - 1 and j != 0 and j!= nr - 1):
T[i, j] = ae * ((T[i, j + 1]) / ap) + aw * ((T[i, j - 1]) / ap) + an * ((T[i - 1, j]) / ap) + asul * (
(T[i + 1, j]) / ap) + 1846.35 * Z * (R ** 2) * (i - 1/2) / ((nr ** 2) * nz * ap) + aef / ap
print(T)
The problem with your code is you have interchanged nr(rows) and nz(columns) with the iterators i and j; Your two loops must be as shown below and change all if, elif conditions on i with (nr-1) and on j with (nz-1). It works fine.
for i in range(0, nr, 1):
for j in range(0, nz, 1):

'SYMBOL' object is not callable

this is my first time with sympy and I don't know what I'm doing wrong. Could you help me please?
This is my code:
from __future__ import division
from sympy import *
q, l, p = symbols('q, l, p')
x1, x2, x3, x4, x5, x6, x7 = symbols('x1, x2, x3, x4, x5, x6, x7')
c1, c2, c3, c4, c5, c6, c7 = symbols('c1, c2, c3, c4, c5, c6, c7')
c8, c9, c10, c11, c12, c13, c14 = symbols('c8, c9, c10, c11, c12, c13, c14')
a = 209 * q * l / 42 - p / 3
"TRECHO AB"
m1 = a * x1 - q * x1 ** 2 / 2
d1 = integrate(m1, x1) + c1
y1 = integrate(d1, x1) + c2
"TRECHO BC"
m2 = a * 2 * l + a * x2 - 2 * q * l(x2 + l)
d2 = integrate(m2, x2) + c3
y2 = integrate(d2, x2) + c4
"TRECHO CD"
m3 = a(3 * l + x3) - 2 * q * l(2 * l + x3) - q * x3 ** 3 / 6 * l
d3 = integrate(m3, x3) + c5
y3 = integrate(d3, x3) + c6
"TRECHO DE"
m4 = a(x4 + 6 * l) - 2 * q * l(x4 + 5 * l) - (9 * q * l / 2)(x4 + l)
d4 = integrate(m4, x4) + c7
y4 = integrate(d3, x4) + c8
"TRECHO FG"
m5 = a(x5 + 7 * l) - 2 * q * l(x5 + 6 * l) - (9 * q * l / 2)(x5 + 2 * l) - p * x5
d5 = integrate(m5, x5) + c9
y5 = integrate(d5, x5) + c10
"TRECHO GH"
m6 = a(x6 + 15 * l / 2) - 2 * q * l(x6 + 13 * l / 2) - (9 * q * l / 2)(x6 + 5 * l / 2) - p(x6 + l / 2) - 2 * q * x6(
x6 / 2)
d6 = integrate(m6, x6) + c11
y6 = integrate(d6, x6) + c12
"TRECHO HI"
m7 = a(x7 + 19 * l / 2) - 2 * q * l(x7 + 17 * l / 2) - (9 * q * l / 2)(x7 + 9 * l / 2) - p(x7 + 5 * l / 2) - 4 * q * l(
x7 + l) - (3 * q * x7 ** 2 / 2 * l)(x7 / 3)
d7 = integrate(m7, x7) + c13
y7 = integrate(d7, x7) + c14
print(
"{},\n{},\n{},\n{},\n{},\n{},\n{},\n{},\n{},\n{},\n{},\n{},\n{},\n{}".format(d1, y1, d2, y2, d3, y3, d4, y4, d5, y5,
d6, y6, d7, y7))
The traceback:
Traceback (most recent call last):
File "mecsolidos2.py", line 17, in <module>
m2 = a * 2 * l + a * x2 - 2 * q * l(x2 + l)
TypeError: 'Symbol' object is not callable
That is the same error to m3 through m7 :S
I've tried to change m2 to another constant, used m2 as m2.eval but none of that worked :S
What pissed me of was that for m1 it worked perfectly
ps: sorry for my bad english
If l() is intended as a function, it should be declared somewhere. If you wish, in SymPy you can have functions without giving its internal details, e.g. as l = Function('l')(x). More details in the documentation.
If, on the contrary, l(...) is meant to be just a multiplication (as suggested by your symbols declaration and the use of l as a scalar elsewhere), the multiplication (*) needs to be written explicitly.
Note that for SymPy to work optimally, when declaring symbols, it helps to specify their type. For example symbols(".....", real=True). Also, specifying whether some variable is always positive can help, especially when logarithms or sqrt are involved. See the documentation for more details about the possible types of assumptions.
By the way, if you prefer a looser syntax, where the multiplication symbol can be omitted and ^ can get converted to **, the sympify() or parse_expr() functions might be interesting.

Texture the 3D figure (cylinder)

I need to texture my cylinder, I have texture.png and i already did a
polygonal mesh (with triangles).
Here is the code if you need
pastebin
import pyglet
import pyglet.gl as pgl
from pyglet.window import key
import math
win = pyglet.window.Window(1300, 1000, resizable=True)
WINDOW = 1000
tr = 90
INCREMENT = 5
transparant = False
xRotation = -70
zRotation = -30
yRotation = 180
zoom = 1
far = 100
dist = 35
x = -180
y = 70
z = 0
light = False
param = 0
t_prev = -5
start_loop = False
run_loop = False
def run_loop(dt):
on_draw()
def draw_figure():
angle = 0
t = 0
x = y = z = 0
a = 50
b = 100
if not transparant:
pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_FILL)
else:
pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_LINE)
pgl.glBegin(pgl.GL_TRIANGLE_STRIP)
for i in range(0, tr + 1):
pgl.glColor3ub(0, 0, 0)
if i >= 1:
t1 = a1
t2 = a2
t3 = a3
a1 = x + a * math.cos(i * 2 * math.pi / tr)
a2 = y + b * math.sin(i * 2 * math.pi / tr)
a3 = z + 8
pgl.glVertex3f(a1, a2, a3)
if i >= 1:
pgl.glNormal3f((b2 - t2) * (a3 - b3) - (b3 - t3) * (a2 - b2), (b3 - t3) * (a1 - b1) - (b1 - t1) * (a3 - b3),
(b1 - t1) * (a2 - b2) - (b2 - t2) * (a1 - b1))
b1 = x
b2 = y
b3 = z + 8
pgl.glVertex3f(b1, b2, b3)
pgl.glEnd()
for j in range(1, 27):
pgl.glBegin(pgl.GL_TRIANGLE_STRIP)
pgl.glColor3ub(0, 0, 0)
x1 = a * math.cos(0)
y1 = b * math.sin(0)
a1 = x1 * math.cos(t * math.pi / 360) + y1 * math.sin(t * math.pi / 360)
a2 = - x1 * math.sin(t * math.pi / 360) + y1 * math.cos(t * math.pi / 360)
a3 = z + j * 8
pgl.glVertex3f(a1, a2, a3)
x1 = a * math.cos(0)
y1 = b * math.sin(0)
b1 = x1 * math.cos((t + 16) * math.pi / 360) + y1 * math.sin((t + 16) * math.pi / 360)
b2 = - x1 * math.sin((t + 16) * math.pi / 360) + y1 * math.cos((t + 16) * math.pi / 360)
b3 = z + j * 8 + 8
pgl.glVertex3f(b1, b2, b3)
for i in range(1, tr + 1):
pgl.glColor3ub(0, 0, 0)
x1 = a * math.cos(i * 2 * math.pi / tr)
y1 = b * math.sin(i * 2 * math.pi / tr)
t1 = a1
t2 = a2
t3 = a3
a1 = x1 * math.cos(t * math.pi / 360) + y1 * math.sin(t * math.pi / 360)
a2 = - x1 * math.sin(t * math.pi / 360) + y1 * math.cos(t * math.pi / 360)
a3 = z + j * 8
pgl.glNormal3f((b2 - t2) * (a3 - b3) - (b3 - t3) * (a2 - b2), (b3 - t3) * (a1 - b1) - (b1 - t1) * (a3 - b3),
(b1 - t1) * (a2 - b2) - (b2 - t2) * (a1 - b1))
pgl.glVertex3f(a1, a2, a3)
x1 = a * math.cos(i * 2 * math.pi / tr)
y1 = b * math.sin(i * 2 * math.pi / tr)
b1 = x1 * math.cos((t + 16) * math.pi / 360) + y1 * math.sin((t + 16) * math.pi / 360)
b2 = - x1 * math.sin((t + 16) * math.pi / 360) + y1 * math.cos((t + 16) * math.pi / 360)
b3 = z + j * 8 + 8
pgl.glVertex3f(b1, b2, b3)
t = t + 16
pgl.glEnd()
pgl.glBegin(pgl.GL_TRIANGLE_STRIP)
t = 416
z = z + 144
angle = angle + t
for i in range(0, tr + 1):
pgl.glColor3ub(0, 0, 0)
x1 = x + a * math.cos(i * 2 * math.pi / tr)
y1 = y + b * math.sin(i * 2 * math.pi / tr)
x2 = x1 * math.cos(t * math.pi / 360) + y1 * math.sin(t * math.pi / 360)
y2 = - x1 * math.sin(t * math.pi / 360) + y1 * math.cos(t * math.pi / 360)
if i >= 1:
t1 = a1
t2 = a2
t3 = a3
a1 = x2
a2 = y2
a3 = z + 72
pgl.glVertex3f(a1, a2, a3)
if i >= 1:
pgl.glNormal3f((b2 - t2) * (a3 - b3) - (b3 - t3) * (a2 - b2), (b3 - t3) * (a1 - b1) - (b1 - t1) * (a3 - b3),
(b1 - t1) * (a2 - b2) - (b2 - t2) * (a1 - b1))
b1 = x
b2 = y
b3 = z + 72
pgl.glVertex3f(b1, b2, b3)
angle = angle + i
pgl.glEnd()
#win.event
def on_draw():
global x, y, z, start_loop, run_loop, param, t_prev, zRotation
pgl.glClearColor(0.3, 0.3, 0.3, 0.0)
pgl.glEnable(pgl.GL_DEPTH_TEST)
if light:
pgl.glEnable(pgl.GL_LIGHTING)
pgl.glLightModelf(pgl.GL_LIGHT_MODEL_TWO_SIDE, pgl.GL_TRUE)
pgl.glEnable(pgl.GL_NORMALIZE)
pgl.glClear(pgl.GL_COLOR_BUFFER_BIT | pgl.GL_DEPTH_BUFFER_BIT)
pgl.glLoadIdentity()
pgl.glViewport(0, 0, 1300, 1000)
pgl.glMatrixMode(pgl.GL_PROJECTION)
pgl.glLoadIdentity()
pgl.glOrtho(-1300 / 4, 1300 / 4, -1000 / 4, 1000 / 4, -400, 600)
pgl.glMatrixMode(pgl.GL_MODELVIEW)
pgl.glLoadIdentity()
if light:
material_diffuse = [1.0, 1.0, 1.0, 1.0]
pgl.glMaterialfv(pgl.GL_FRONT_AND_BACK, pgl.GL_DIFFUSE,
(pgl.GLfloat * len(material_diffuse))(*material_diffuse))
light5_diffuse = [1.0, 0.0, 0.0];
light5_position = [0.5, 0.5, 1.0, 0];
pgl.glEnable(pgl.GL_LIGHT5);
pgl.glLightfv(pgl.GL_LIGHT5, pgl.GL_DIFFUSE, (pgl.GLfloat * len(light5_diffuse))(*light5_diffuse));
pgl.glLightfv(pgl.GL_LIGHT5, pgl.GL_POSITION, (pgl.GLfloat * len(light5_position))(*light5_position));
pgl.glLightf(pgl.GL_LIGHT5, pgl.GL_CONSTANT_ATTENUATION, 0.0);
pgl.glLightf(pgl.GL_LIGHT5, pgl.GL_LINEAR_ATTENUATION, 0.4);
pgl.glLightf(pgl.GL_LIGHT5, pgl.GL_QUADRATIC_ATTENUATION, 0.8);
light6_diffuse = [0.0, 1.0, 0.0];
light6_position = [0.5 * math.cos(2 * math.pi / 3), 0.5 * math.sin(2 * math.pi / 3), 1.0, 0];
pgl.glEnable(pgl.GL_LIGHT6);
pgl.glLightfv(pgl.GL_LIGHT6, pgl.GL_DIFFUSE, (pgl.GLfloat * len(light6_diffuse))(*light6_diffuse));
pgl.glLightfv(pgl.GL_LIGHT6, pgl.GL_POSITION, (pgl.GLfloat * len(light6_position))(*light6_position));
pgl.glLightf(pgl.GL_LIGHT6, pgl.GL_CONSTANT_ATTENUATION, 0.0);
pgl.glLightf(pgl.GL_LIGHT6, pgl.GL_LINEAR_ATTENUATION, 0.4);
pgl.glLightf(pgl.GL_LIGHT6, pgl.GL_QUADRATIC_ATTENUATION, 0.8);
light7_diffuse = [0.0, 0.0, 1.0];
light7_position = [0.5 * math.cos(4 * math.pi / 3), 0.5 * math.sin(4 * math.pi / 3), 1.0, 0];
pgl.glEnable(pgl.GL_LIGHT7);
pgl.glLightfv(pgl.GL_LIGHT7, pgl.GL_DIFFUSE, (pgl.GLfloat * len(light7_diffuse))(*light7_diffuse));
pgl.glLightfv(pgl.GL_LIGHT7, pgl.GL_POSITION, (pgl.GLfloat * len(light7_position))(*light7_position));
pgl.glLightf(pgl.GL_LIGHT7, pgl.GL_CONSTANT_ATTENUATION, 0.0);
pgl.glLightf(pgl.GL_LIGHT7, pgl.GL_LINEAR_ATTENUATION, 0.4);
pgl.glLightf(pgl.GL_LIGHT7, pgl.GL_QUADRATIC_ATTENUATION, 0.8);
pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_FILL)
pgl.glPushMatrix()
pgl.glTranslatef(x, y, z)
pgl.glRotatef(xRotation, 1, 0, 0)
pgl.glRotatef(yRotation, 0, 1, 0)
pgl.glRotatef(zRotation, 0, 0, 1)
pgl.glScalef(zoom, zoom, zoom)
draw_figure()
if start_loop:
start_loop = False
run_loop = True
x = ((1 - (param / 100)) ** 3) * (-180) + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (100) + 3 * (
(param / 100) ** 2) * (
1 - (param / 100)) * (0) + ((param / 100) ** 3) * (200)
y = ((1 - (param / 100)) ** 3) * 70 + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (140) + 3 * (
(param / 100) ** 2) * (
1 - (param / 100)) * (140) + ((param / 100) ** 3) * (
70)
z = ((1 - (param / 100)) ** 3) * 0 + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (100) + 3 * (
(param / 100) ** 2) * (
1 - (param / 100)) * (100) + ((param / 100) ** 3) * (
0)
elif run_loop:
if param < 100 and param > t_prev:
zRotation += INCREMENT
param = param + 1
t_prev = t_prev + 1
if (param == 100):
t_prev = 105
x = ((1 - (param / 100)) ** 3) * (-180) + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (100) + 3 * (
(param / 100) ** 2) * (1 - (param / 100)) * (0) + ((param / 100) ** 3) * (200)
y = ((1 - (param / 100)) ** 3) * 70 + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (140) + 3 * (
(param / 100) ** 2) * (1 - (param / 100)) * (140) + ((param / 100) ** 3) * (
70)
z = ((1 - (param / 100)) ** 3) * 0 + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (100) + 3 * (
(param / 100) ** 2) * (1 - (param / 100)) * (100) + ((param / 100) ** 3) * (
0)
print(param)
print("плюс")
if param > 0 and param < t_prev:
zRotation -= INCREMENT
param = param - 1
t_prev = t_prev - 1
if (param == 0):
t_prev = -5
x = ((1 - (param / 100)) ** 3) * (-180) + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (100) + 3 * (
(param / 100) ** 2) * (1 - (param / 100)) * (0) + ((param / 100) ** 3) * (200)
y = ((1 - (param / 100)) ** 3) * 70 + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (140) + 3 * (
(param / 100) ** 2) * (1 - (param / 100)) * (140) + ((param / 100) ** 3) * (
70)
z = ((1 - (param / 100)) ** 3) * 0 + 3 * (param / 100) * ((1 - (param / 100)) ** 2) * (100) + 3 * (
(param / 100) ** 2) * (1 - (param / 100)) * (100) + ((param / 100) ** 3) * (
0)
print(param)
print("минус")
pgl.glPopMatrix()
#win.event
def on_text_motion(motion):
global xRotation, yRotation, INCREMENT
if motion == key.UP:
xRotation -= INCREMENT
elif motion == key.DOWN:
xRotation += INCREMENT
elif motion == key.LEFT:
yRotation -= INCREMENT
elif motion == key.RIGHT:
yRotation += INCREMENT
#win.event
def on_key_press(symbol, modifiers):
global transparant, dist, tr, x, y, z, INCREMENT, zRotation, light, t, start_loop, run_loop
if symbol == key.T and not transparant:
transparant = True
elif symbol == key.T and transparant:
transparant = False
elif symbol == key.W:
x += 2.5
elif symbol == key.S:
x -= 2.5
elif symbol == key.A:
y -= 2.5
elif symbol == key.D:
y += 2.5
elif symbol == key.Q:
z -= 2.5
elif symbol == key.E:
z += 2.5
elif symbol == key.L:
light = not light
elif symbol == key.Z:
zRotation += INCREMENT
elif symbol == key.X:
zRotation -= INCREMENT
elif symbol == key.ESCAPE:
pyglet.app.exit()
elif symbol == key.P:
tr += 5
elif symbol == key.O:
if tr > 5:
tr -= 5
elif symbol == key.SPACE:
if not run_loop:
start_loop = True
else:
run_loop = False
#win.event
def on_mouse_scroll(x, y, scroll_x, scroll_y):
global zoom
if scroll_y < 0:
zoom += 0.1
elif scroll_y > 0 and zoom - 0.1 > 0:
zoom -= 0.1
#win.event
def on_mouse_press(x, y, button, modifiers):
if button == pyglet.window.mouse.LEFT:
print(x, y)
pyglet.clock.schedule_interval(run_loop, 0.1)
pyglet.app.run()
Edit:
First you have to load the texture image to a texture object by pyglet.image.load respectively get_texture():
texture_obj = pyglet.image.load('texture.png').get_texture()
The texture has to be bound by glBindTexture:
pgl.glBindTexture(pgl.GL_TEXTURE_2D, texture_obj.id)
Two-dimensional texturing is enabled by glEnable(GL_TEXTURE_2D) and can be disabled by glDisable(GL_TEXTURE_2D).
If texturing is enables then the texture wich is currently bound when the geometry is drawn by the glBegin/glEnd sequence is applied:
pgl.glEnable(pgl.GL_TEXTURE_2D)
If texturing is enabled, then by default the color of the texel is multiplied by the current color, because by default the texture environment mode (GL_TEXTURE_ENV_MODE) is GL_MODULATE. See glTexEnv.
This causes that the color of the texels of the texture is "mixed" by the last color which you have set by glColor3ub.
Set a "white" color before you render the texture, to solve your issue:
plg.glColor3ub(255, 255, 255)
or
pgl.glColor3f(1, 1, 1)
Likewise you can change the environment mode to GL_REPLACE, instead:
pgl.glTexEnvi(pgl.GL_TEXTURE_ENV, pgl.GL_TEXTURE_ENV_MODE, pgl.GL_REPLACE)
When glVertex is called, the the current texture coordinates are associated with the vertex coordinate. The texture coordinate is set by glTexCoord2f.
You've to set the texture coordinates corresponding to each vertex coordinate. The texture coordinates have to be in range [0, 1]. See also How do opengl texture coordinates work?.
e.g.
u = math.cos(i * 2 * math.pi / tr)
v = math.sin(i * 2 * math.pi / tr)
pgl.glTexCoord2f(u*0.5+0.5, v*0.5+0.5)
a1 = x + a * u
a2 = y + b * v
a3 = z + 8
pgl.glVertex3f(a1, a2, a3)
The function draw_figure may look as follows. Note, I don't exactly know how you want to wrap the texture to the mesh, so I calculate the texture coordinates as I thought. You may have to a adapt the calculation of the texture coordinates to your needs:
texture_obj = None
def draw_figure():
global texture_obj
# [...]
if texture_obj == None:
texture_obj = pyglet.image.load('texture.png').get_texture()
pgl.glBindTexture(pgl.GL_TEXTURE_2D, texture_obj.id)
pgl.glEnable(pgl.GL_TEXTURE_2D)
pgl.glTexEnvi(pgl.GL_TEXTURE_ENV, pgl.GL_TEXTURE_ENV_MODE, pgl.GL_REPLACE)
if not transparant:
pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_FILL)
else:
pgl.glPolygonMode(pgl.GL_FRONT_AND_BACK, pgl.GL_LINE)
pgl.glBegin(pgl.GL_TRIANGLE_STRIP)
for i in range(0, tr + 1):
pgl.glColor3ub(255, 255, 255)
if i >= 1:
t1 = a1
t2 = a2
t3 = a3
u = math.cos(i * 2 * math.pi / tr)
v = math.sin(i * 2 * math.pi / tr)
a1 = x + a * u
a2 = y + b * v
a3 = z + 8
pgl.glTexCoord2f(u*0.5+0.5, v*0.5+0.5)
pgl.glVertex3f(a1, a2, a3)
if i >= 1:
pgl.glNormal3f((b2 - t2) * (a3 - b3) - (b3 - t3) * (a2 - b2), (b3 - t3) * (a1 - b1) - (b1 - t1) * (a3 - b3),
(b1 - t1) * (a2 - b2) - (b2 - t2) * (a1 - b1))
b1 = x
b2 = y
b3 = z + 8
pgl.glTexCoord2f(0.5, 0.5)
pgl.glVertex3f(b1, b2, b3)
pgl.glEnd()
for j in range(1, 27):
pgl.glBegin(pgl.GL_TRIANGLE_STRIP)
pgl.glColor3ub(255, 255, 255)
x1 = a * math.cos(0)
y1 = b * math.sin(0)
a1 = x1 * math.cos(t * math.pi / 360) + y1 * math.sin(t * math.pi / 360)
a2 = - x1 * math.sin(t * math.pi / 360) + y1 * math.cos(t * math.pi / 360)
a3 = z + j * 8
pgl.glTexCoord2f(0.0, 0.0)
pgl.glVertex3f(a1, a2, a3)
b1 = x1 * math.cos((t + 16) * math.pi / 360) + y1 * math.sin((t + 16) * math.pi / 360)
b2 = - x1 * math.sin((t + 16) * math.pi / 360) + y1 * math.cos((t + 16) * math.pi / 360)
b3 = z + j * 8 + 8
u = math.cos((t + 16) * math.pi / 360) + math.sin((t + 16) * math.pi / 360)
v = (j-1)/26
pgl.glTexCoord2f(0.0, 0.0)
pgl.glVertex3f(b1, b2, b3)
for i in range(1, tr + 1):
pgl.glColor3ub(255, 255, 255)
x1 = a * math.cos(i * 2 * math.pi / tr)
y1 = b * math.sin(i * 2 * math.pi / tr)
t1 = a1
t2 = a2
t3 = a3
a1 = x1 * math.cos(t * math.pi / 360) + y1 * math.sin(t * math.pi / 360)
a2 = - x1 * math.sin(t * math.pi / 360) + y1 * math.cos(t * math.pi / 360)
a3 = z + j * 8
pgl.glNormal3f((b2 - t2) * (a3 - b3) - (b3 - t3) * (a2 - b2), (b3 - t3) * (a1 - b1) - (b1 - t1) * (a3 - b3),
(b1 - t1) * (a2 - b2) - (b2 - t2) * (a1 - b1))
v = math.cos(t * math.pi / 360) + math.sin(t * math.pi / 360)
pgl.glTexCoord2f((i-1)/tr, (26-j)/26)
pgl.glVertex3f(a1, a2, a3)
x1 = a * math.cos(i * 2 * math.pi / tr)
y1 = b * math.sin(i * 2 * math.pi / tr)
b1 = x1 * math.cos((t + 16) * math.pi / 360) + y1 * math.sin((t + 16) * math.pi / 360)
b2 = - x1 * math.sin((t + 16) * math.pi / 360) + y1 * math.cos((t + 16) * math.pi / 360)
b3 = z + j * 8 + 8
v = math.cos((t + 16) * math.pi / 360) + math.sin((t + 16) * math.pi / 360)
pgl.glTexCoord2f((i-1)/tr, (25-j)/26)
pgl.glVertex3f(b1, b2, b3)
t = t + 16
pgl.glEnd()
pgl.glBegin(pgl.GL_TRIANGLE_STRIP)
t = 416
z = z + 144
angle = angle + t
for i in range(0, tr + 1):
pgl.glColor3ub(255, 255, 255)
u = math.cos(i * 2 * math.pi / tr)
v = math.sin(i * 2 * math.pi / tr)
x1 = x + a * u
y1 = y + b * v
x2 = x1 * math.cos(t * math.pi / 360) + y1 * math.sin(t * math.pi / 360)
y2 = - x1 * math.sin(t * math.pi / 360) + y1 * math.cos(t * math.pi / 360)
if i >= 1:
t1 = a1
t2 = a2
t3 = a3
a1 = x2
a2 = y2
a3 = z + 72
pgl.glTexCoord2f(u*0.5+0.5, v*0.5+0.5)
pgl.glVertex3f(a1, a2, a3)
if i >= 1:
pgl.glNormal3f((b2 - t2) * (a3 - b3) - (b3 - t3) * (a2 - b2), (b3 - t3) * (a1 - b1) - (b1 - t1) * (a3 - b3),
(b1 - t1) * (a2 - b2) - (b2 - t2) * (a1 - b1))
b1 = x
b2 = y
b3 = z + 72
pgl.glTexCoord2f(0.5, 0.5)
pgl.glVertex3f(b1, b2, b3)
angle = angle + i
pgl.glEnd()

Categories