I am trying to understand why the isometric view is not correct. The most accurate representation is at 55 degrees with the vertical axis, and 45 with the horizontal. In the mcve there are two points who should be aligned at 45 degrees on each axis. I have set up a camera movement based in the sphere algebra definition. The edges of the planes should coincide, but they do not.
MCVE:
from OpenGL.GL import glClear, GL_COLOR_BUFFER_BIT, glEnable, GL_DEPTH_TEST, glMatrixMode, GL_PROJECTION, \
glLoadIdentity, glOrtho, glClearColor, GL_DEPTH_BUFFER_BIT, GL_MODELVIEW, glLineWidth, glBegin, glColor, glVertex, \
glEnd, glPointSize, GL_POINT_SMOOTH, GL_POINTS, GL_BLEND, glBlendFunc, GL_SRC_ALPHA, \
GL_QUADS, glDisable, GL_LINES, GL_LINE_LOOP, glDepthMask, GL_FALSE, GL_TRUE, GL_ONE_MINUS_SRC_ALPHA
from OpenGL.GLU import gluLookAt
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QOpenGLWidget
from math import sin, cos, radians
class Renderizador(QOpenGLWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.dx = 0
self.dy = 0
self.dz = 0
self.theta = 405
self.phi = 45
self.x = sin(radians(self.theta)) * cos(radians(self.phi)) + self.dx
self.z = sin(radians(self.theta)) * sin(radians(self.phi)) + self.dz
self.y = cos(radians(self.theta)) + self.dy
self.vertices_vertical = ((100, 100, 0), (-100, 100, 0), (-100, 0, 0), (100, 0, 0))
self.vertices_vertical_debajo = ((100, 0, 0), (-100, 0, 0), (-100, -100, 0), (100, -100, 0))
self.vertices_horizontal = ((100, 0, 0), (100, 0, 100), (-100, 0, 100), (-100, 0, 0))
self.vertices_horizontal_detras = ((100, 0, 0), (100, 0, -100), (-100, 0, -100), (-100, 0, 0))
self.vertices_borde_v = ((100, 100, 0), (100, -100, 0), (-100, -100, 0), (-100, 100, 0))
self.vertices_borde_h = ((100, 0, 100), (-100, 0, 100), (-100, 0, -100), (100, 0, -100))
self.puntos = [("a", 1, 1, 1), ("b", 10, 10, 10)]
def recalcular(self):
self.x = sin(radians(self.theta)) * cos(radians(self.phi)) + self.dx
self.z = sin(radians(self.theta)) * sin(radians(self.phi)) + self.dz
self.y = cos(radians(self.theta)) + self.dy
gluLookAt(self.x, self.y, self.z, self.dx, self.dy, self.dz, 0, 1, 0)
self.update()
def dibujar_planos(self):
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glDepthMask(GL_FALSE)
glBegin(GL_QUADS)
glColor(1, 0, 0, 0.5)
for vertex in range(4):
glVertex(self.vertices_horizontal_detras[vertex])
glColor(0, 1, 0, 0.5)
for vertex in range(4):
glVertex(self.vertices_vertical_debajo[vertex])
glColor(0, 1, 0, 0.5)
for vertex in range(4):
glVertex(self.vertices_vertical[vertex])
glColor(1, 0, 0, 0.5)
for vertex in range(4):
glVertex(self.vertices_horizontal[vertex])
glEnd()
glDepthMask(GL_TRUE)
glDisable(GL_BLEND)
glLineWidth(1)
glColor(0.2, 1, 0.2, 0.5)
glBegin(GL_LINE_LOOP)
for vertex in range(4):
glVertex(self.vertices_borde_v[vertex])
glColor(1, 0.2, 0.2, 0.5)
glEnd()
glBegin(GL_LINE_LOOP)
for vertex in range(4):
glVertex(self.vertices_borde_h[vertex])
glEnd()
@staticmethod
def dibujar_ejes():
glLineWidth(3)
glBegin(GL_LINES)
# X ROJO
glColor(1, 0, 0)
glVertex(0, 0, 0)
glVertex(10, 0, 0)
# Y VERDE
glColor(0, 1, 0)
glVertex(0, 0, 0)
glVertex(0, 10, 0)
# Z AZUL
glColor(0, 0, 1)
glVertex(0, 0, 0)
glVertex(0, 0, 10)
glEnd()
def dibujar_punto(self):
glColor(0, 0, 0, 0)
glPointSize(4)
glEnable(GL_POINT_SMOOTH)
glBegin(GL_POINTS)
for i in range(len(self.puntos)):
glVertex(self.puntos[i][1], self.puntos[i][3], self.puntos[i][2])
glEnd()
# self.x = sin(radians(self.theta)) * cos(radians(self.phi)) + self.dx
# self.z = sin(radians(self.theta)) * sin(radians(self.phi)) + self.dz
# self.y = cos(radians(self.theta)) + self.dy
# gluLookAt(self.x, self.y, self.z, self.dx, self.dy, self.dz, 0, 1, 0)
self.update()
def initializeGL(self):
glEnable(GL_DEPTH_TEST)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(100, -100, -100, 100, -500, 150)
glMatrixMode(GL_MODELVIEW)
def paintGL(self):
glClearColor(1, 1, 1, 0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
up = 1
if self.theta == 360:
up = -1
gluLookAt(self.x, self.y, self.z, self.dx, self.dy, self.dz, 0, up, 0)
self.dibujar_ejes()
self.dibujar_planos()
self.dibujar_punto()
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_W:
self.theta -= 5
elif event.key() == QtCore.Qt.Key_A:
self.phi -= 5
elif event.key() == QtCore.Qt.Key_S:
self.theta += 5
elif event.key() == QtCore.Qt.Key_D:
self.phi += 5
elif event.key() == QtCore.Qt.Key_Q:
self.dz += 1
elif event.key() == QtCore.Qt.Key_E:
self.dz -= 1
elif event.key() == QtCore.Qt.Key_Left:
self.dx -= 1
elif event.key() == QtCore.Qt.Key_Up:
self.dy += 1
elif event.key() == QtCore.Qt.Key_Right:
self.dx += 1
elif event.key() == QtCore.Qt.Key_Down:
self.dy -= 1
if self.theta < 360:
self.theta = 360
if self.theta > 540:
self.theta = 540
if self.phi >= 360:
self.phi -= 360
if self.phi < 0:
self.phi += 360
self.x = sin(radians(self.theta)) * cos(radians(self.phi)) + self.dx
self.z = sin(radians(self.theta)) * sin(radians(self.phi)) + self.dz
self.y = cos(radians(self.theta)) + self.dy
ui.actualizar()
self.update()
super().keyPressEvent(event)
class UiVentana(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(UiVentana, self).__init__(parent)
ventana.resize(1500, 1015)
self.widget_central = QtWidgets.QWidget(ventana)
self.Renderizador = Renderizador(self.widget_central)
self.Renderizador.setGeometry(QtCore.QRect(0, 0, 1000, 1000))
self.Renderizador.setFocusPolicy(QtCore.Qt.StrongFocus)
self.label_5 = QtWidgets.QLabel(self.widget_central)
self.label_5.setGeometry(QtCore.QRect(1110, 49, 160, 20))
self.label_6 = QtWidgets.QLabel(self.widget_central)
self.label_6.setGeometry(QtCore.QRect(1010, 70, 111, 16))
self.label_7 = QtWidgets.QLabel(self.widget_central)
self.label_7.setGeometry(QtCore.QRect(1130, 70, 130, 16))
self.label_5.setText("X: Y: Z:")
self.label_6.setText("Ángulo vertical:")
self.label_7.setText("Ángulo horizontal:")
ventana.setCentralWidget(self.widget_central)
ventana.show()
def actualizar(self):
x = round(100 * (sin(radians(self.Renderizador.theta)) * cos(radians(self.Renderizador.phi)))
+ self.Renderizador.dx, 2)
z = round(100 * (sin(radians(self.Renderizador.theta)) * sin(radians(self.Renderizador.phi)))
+ self.Renderizador.dz, 2)
y = round(100 * (cos(radians(self.Renderizador.theta))) + self.Renderizador.dy, 2)
theta = self.Renderizador.theta - 360
phi = self.Renderizador.phi
if x == -0:
x = 0
if y == -0:
y = 0
if z == -0:
z = 0
self.label_5.setText("X: {} Y: {} Z: {}".format(x, z, y))
self.label_6.setText("Ángulo vertical: " + str(theta))
self.label_7.setText("Ángulo horizontal: " + str(phi))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication([])
ventana = QtWidgets.QMainWindow()
ui = UiVentana()
sys.exit(app.exec_())