Я пытаюсь создать программу, которая визуализирует объект в 3D и которую вы можете вращать и контролировать с помощью положения мыши. Я пытаюсь отобразить лица объекта, но не знаю, как мне сначала отобразить более близкие лица, чтобы перед более близкими лицами не отображалось «фоновое» лицо.
код, который я предоставил, полностью воспроизводим, просто скопируйте и вставьте его, если у вас есть tkinter и numpy.
from numpy import *
from tkinter import *
#eulers angles matrixes
def Rx(theta):
return mat(mat([[1, 0 , 0 ],
[0, cos(theta), -sin(theta)],
[0, sin(theta), cos(theta) ]]).round(15))
def Ry(theta):
return mat(mat([[cos(theta), 0, -sin(theta)],
[ 0 , 1, 0 ],
[sin(theta), 0, cos(theta) ]]).round(15))
def Rz(theta):
return mat(mat([[cos(theta), -sin(theta), 0],
[sin(theta), cos(theta) , 0],
[ 0 , 0 , 1]]).round(15))
#returns a 2d projection matrix,
def proj2d(p):
return mat(eye(2,3)*p)
#tuple into vector
def vector(tuple):
return transpose(mat(list(tuple)))
#updates position of the 3D point in function of the x,y,z angles
def position(pts3d,anglex,angley,anglez):
for i in range(len(pts3d)):
pts3d[i] = (float((Rx(anglex) * vector(pts3d[i]))[0]),
float((Rx(anglex) * vector(pts3d[i]))[1]),
float((Rx(anglex) * vector(pts3d[i]))[2]))
pts3d[i] = (float((Ry(angley) * vector(pts3d[i]))[0]),
float((Ry(angley) * vector(pts3d[i]))[1]),
float((Ry(angley) * vector(pts3d[i]))[2]))
pts3d[i] = (float((Rz(anglez) * vector(pts3d[i]))[0]),
float((Rz(anglez) * vector(pts3d[i]))[1]),
float((Rz(anglez) * vector(pts3d[i]))[2]))
#makes a projection of the 3d points on the 2d screen
def projected(pts3d):
pts2d = []
for i in pts3d:
pts2d.append((float((proj2d(30+0.75*i[2]) * vector(i))[0]),
float((proj2d(30+0.75*i[2]) * vector(i))[1])))
return pts2d
#displays dots
def dots(canvas,points):
for i in points:
canvas.create_oval(H/2+5+i[0],H/2+5+i[1],H/2-5+i[0],H/2-5+i[1],fill = 'white')
#displays vertices
def connect(canvas,vertics,points):
for i in vertics:
canvas.create_line(H/2+points[int(i[0])][0],H/2+points[int(i[0])][1],H/2+points[int(i[1])][0],H/2+points[int(i[1])][1],width = 2,fill = 'white')
#what I should modify, I guess: it's the funtion that displays the faces of the object
def face(canvas,faces,points,colors):
for i in range(len(faces)):
coordsface = ()
for j in faces[i]:
coordsface += (H/2+points[int(j)][0],H/2+points[int(j)][1])
canvas.create_polygon(coordsface,fill = colors[i])
#major functions, updates position each time interval(delay)
def updateposition(self,H,canvas,points,vertics,faces,clrfc,delai,domegax,domegay,domegaz):
canvas.delete('all')
y,x = self.winfo_pointerx() - self.winfo_rootx() - H/2, self.winfo_pointery() - self.winfo_rooty() - H/2
if abs(x) >= H/2 or abs(y) >= H/2: x,y = 0,0
domegax -= 0.00001*(x)
domegay -= 0.00001*(y)
position(points,domegax,domegay,domegaz)
if affpts == 'y':
dots(canvas,projected(points))
if affart == 'y':
connect(canvas,vertics,projected(points))
if afffac == 'y':
face(canvas,faces,projected(points),clrfc)
self.after(delai,updateposition,self,H,canvas,points,vertics,faces,clrfc,delai,domegax,domegay,domegaz)
## cube
def pts3Dcube():
#points
a = ( L/2, L/2, L/2)
b = ( L/2, L/2,-L/2)
c = ( L/2,-L/2, L/2)
d = ( L/2,-L/2,-L/2)
e = (-L/2, L/2, L/2)
f = (-L/2, L/2,-L/2)
g = (-L/2,-L/2, L/2)
h = (-L/2,-L/2,-L/2)
pts3d = [a,b,c,d,e,f,g,h]
#vertices
aretes = []
for i in [0,2,4,6]:
aretes.append(str(i)+str(i+1))
for i in [0,1,4,5]:
aretes.append(str(i)+str(i+2))
for i in [0,1,2,3]:
aretes.append(str(i)+str(i+4))
#faces
faces = ['0132','4576','0154','2376','1375','0264']
clrfc = ['green','red','yellow','blue','orange','white']
return pts3d, aretes, faces, clrfc
## initial conditions
L = 5
H = 600
delai = 5
self = Tk()
canvas = Canvas(self,height = H,width = H,bg = 'gray13')
canvas.pack()
objet = pts3Dcube() #object choice
domegax = 0.0
domegay = 0.0
domegaz = 0.0
#initial rotation angles
iomegax = 0
iomegay = 0
iomegaz = 0
#displaying points, vertices, faces or not
affpts = 'y'
affart = 'y'
afffac = 'y'
position(objet[0],iomegax,iomegay,iomegaz) #initial rotation
updateposition(self,H,canvas,objet[0],objet[1],objet[2],objet[3],delai,domegax,domegay,domegaz) # dynamic rotation
если у кого-то из вас есть идея, пожалуйста, прокомментируйте ее или что-то в этом роде, я заблудился.
Спасибо!