• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

C++ OpenGL - tworzenie symulatora robota za pomocą prymitywów - rotacja nie w tym miejscu, w którym powinna być

Object Storage Arubacloud
0 głosów
294 wizyt
pytanie zadane 14 stycznia 2019 w OpenGL, Unity przez heros22pt Użytkownik (950 p.)

Witam, muszę stworzyć "Manipulator RPR" za pomocą prymitywów w OpenGL. Generalnie całość wychodzi ładnie, pierwsza pierwszego elementu spoko, węzeł przesuwny także bez zarzutów. Problem mam z rotowaniem 3. Elementu wokół osi z (jest ona do nas). Nie mam pojęcia dla czego rotuje mi się w ten sposób - nic nie ustawiałem, a rotuje się prawie dobrze, to znaczy 1 jednostkę odległości od lewego końca prostopadłościanu (cały ma 6 jednostek odległości). Chciałbym owy element rotować na samym końcu. Czy mógłby ktoś powiedzieć, co robię nie tak? P.S. jestem początkującym w OpenGL. Niżej zamieszczam kod interesującego mnie elementu:

	/*!!!!!!!!!!!!!!!STARTbloczek numer 3 start : R- */

	glTranslatef(-2.5f, d2-0.5, -20.0f);
	glRotatef(th1, 0, 1, 0);
	glRotatef((float)th3, 0.0f, 0.0f, 1.0f);
	glBegin(GL_QUADS);                // Begin drawing the color cube with 6 quads
	// Top face (y = 1.0f)
	// Define vertices in counter-clockwise (CCW) order with normal pointing out
	glColor3f(0.0f, 1.0f, 0.0f);     // Green

	glVertex3f(6.0f, 0.5f, -0.5f);
	glVertex3f(-0.5f, 0.5f, -0.5f);
	glVertex3f(-0.5f, 0.5f, 0.5f);
	glVertex3f(6.0f, 0.5f, 0.5f);


	// Bottom face (y = -1.0f)
	glColor3f(1.0f, 0.5f, 0.0f);     // Orange

	glVertex3f(6.0f, -0.5f, 0.5f);
	glVertex3f(-0.5f, -0.5f, 0.5f);
	glVertex3f(-0.5f, -0.5f, -0.5f);
	glVertex3f(6.0f, -0.5f, -0.5f);


	// Front face  (z = 1.0f)
	glColor3f(1.0f, 0.0f, 0.0f);     // Red

	glVertex3f(6.0f, 0.5f, 0.5f);
	glVertex3f(-0.5f, 0.5f, 0.5f);
	glVertex3f(-0.5f, -0.5f, 0.5f);
	glVertex3f(6.0f, -0.5f, 0.5f);


	// Back face (z = -1.0f)
	glColor3f(1.0f, 1.0f, 0.0f);     // Yellow

	glVertex3f(6.0f, -0.5f, -0.5f);
	glVertex3f(-0.5f, -0.5f, -0.5f);
	glVertex3f(-0.5f, 0.5f, -0.5f);
	glVertex3f(6.0f, 0.5f, -0.5f);


	// Left face (x = -1.0f)
	glColor3f(0.0f, 0.0f, 1.0f);     // Blue

	glVertex3f(-0.5f, 0.5f, 0.5f);
	glVertex3f(-0.5f, 0.5f, -0.5f);
	glVertex3f(-0.5f, -0.5f, -0.5f);
	glVertex3f(-0.5f, -0.5f, 0.5f);


	// Right face (x = 1.0f)
	glColor3f(1.0f, 0.0f, 1.0f);     // Magenta

	glVertex3f(6.0f, 0.5f, -0.5f);
	glVertex3f(6.0f, 0.5f, 0.5f);
	glVertex3f(6.0f, -0.5f, 0.5f);
	glVertex3f(6.0f, -0.5f, -0.5f);
	glEnd();  // End of drawing color-cube

	/*bloczek numer 3 end : R- */

	glutSwapBuffers();  // Swap the front and back frame buffers (double buffering)

jeśli chodzi o objaśnienie, to "glTranslatef(-2.5f, d2-0.5, -20.0f);" służy do przesunięcia klocka w prawo o 2,5 jednostki odległości, ponieważ człon ma być w "prawo". Dalej przesuwamy w 'y' o wartość węzła przesównego i trochę obniżamy, a ostatnie to oddalenie.

glRotatef(th1, 0, 1, 0); -> służy do rotowania razem z pierwszym węzłem rotacyjnym.

glRotatef((float)th3, 0.0f, 0.0f, 1.0f); -> zapisane w inny sposób niż pierwsze, ale to nie ma znaczenia, rezultat ten sam.

Oto jak wygląda symulacja:

Dodaje też cały kod aplikacji:

/*
* OGL01Shape3D.cpp: 3D Shapes
*/
#include <windows.h>  // for MS Windows
#include <GL/glut.h>  // GLUT, include glu.h and gl.h
#include<iostream>

/* Global variables */
char title[] = "3D Shapes";
float d2 = 2.0;
int th1 = 0;
int th3 = 0;
void FunkcjaDoObslugiKlawiatury(unsigned char key, int mouse_x, int mouse_y) //dla obslugi klawiatury
{
	std::cout << "Naciśnięto klawisz: " << key << ", a myszka znajduje się w pozycji: " << mouse_x << ", " << mouse_y << "(w pikselach)" << std::endl;
	switch (key)
	{
		case 'q':
		{
			th1 += 5;
			break;
		}
		case 'a':
		{
			th1 -= 5;
			break;
		}
		case 'w':
		{
			d2 +=0.1;
			break;
		}
		case 's':
		{
			d2 -= 0.1;
			break;
		}
		case 'e':
		{
			th3 += 5;
			break;
		}
		case 'd':
		{
			th3 -= 5;
			break;
		}
	}
}


/* Initialize OpenGL Graphics */
void initGL() {
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
	glClearDepth(1.0f);                   // Set background depth to farthest
	glutKeyboardFunc(FunkcjaDoObslugiKlawiatury);
	glEnable(GL_DEPTH_TEST);   // Enable depth testing for z-culling
	glDepthFunc(GL_LEQUAL);    // Set the type of depth-test
	glShadeModel(GL_SMOOTH);   // Enable smooth shading
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Nice perspective corrections

}

void idle() {
	glutPostRedisplay();
}

/* Handler for window-repaint event. Called back when the window first appears and
whenever the window needs to be re-painted. */
void display() {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers
	glMatrixMode(GL_MODELVIEW);     // To operate on model-view matrix

	// Render a color-cube consisting of 6 quads with different colors
	glLoadIdentity();                 // Reset the model-view matrix
	
	/*bloczek numer 1 start : R| */
	glTranslatef(-3.0f, -3.0f, -20.0f);  // Move right and into the screen

	glBegin(GL_QUADS);                // Begin drawing the color cube with 6 quads
	// Top face (y = 1.0f)
	// Define vertices in counter-clockwise (CCW) order with normal pointing out
	glColor3f(0.0f, 2.0f, 0.0f);     // Green
	glVertex3f(1.0f, 2.0f, -1.0f);
	glVertex3f(-1.0f, 2.0f, -1.0f);
	glVertex3f(-1.0f, 2.0f, 1.0f);
	glVertex3f(1.0f, 2.0f, 1.0f);

	// Bottom face (y = -1.0f)
	glColor3f(1.0f, 0.5f, 0.0f);     // Orange
	glVertex3f(1.0f, -2.0f, 1.0f);
	glVertex3f(-1.0f, -2.0f, 1.0f);
	glVertex3f(-1.0f, -2.0f, -1.0f);
	glVertex3f(1.0f, -2.0f, -1.0f);

	// Front face  (z = 1.0f)
	glColor3f(1.0f, 0.0f, 0.0f);     // Red
	glVertex3f(1.0f, 2.0f, 1.0f);
	glVertex3f(-1.0f, 2.0f, 1.0f);
	glVertex3f(-1.0f, -2.0f, 1.0f);
	glVertex3f(1.0f, -2.0f, 1.0f);

	// Back face (z = -1.0f)
	glColor3f(1.0f, 2.0f, 0.0f);     // Yellow
	glVertex3f(1.0f, -2.0f, -1.0f);
	glVertex3f(-1.0f, -2.0f, -1.0f);
	glVertex3f(-1.0f, 2.0f, -1.0f);
	glVertex3f(1.0f, 2.0f, -1.0f);

	// Left face (x = -1.0f)
	glColor3f(0.0f, 0.0f, 1.0f);     // Blue
	glVertex3f(-1.0f, 2.0f, 1.0f);
	glVertex3f(-1.0f, 2.0f, -1.0f);
	glVertex3f(-1.0f, -2.0f, -1.0f);
	glVertex3f(-1.0f, -2.0f, 1.0f);

	// Right face (x = 1.0f)
	glColor3f(1.0f, 0.0f, 1.0f);     // Magenta
	glVertex3f(1.0f, 2.0f, -1.0f);
	glVertex3f(1.0f, 2.0f, 1.0f);
	glVertex3f(1.0f, -2.0f, 1.0f);
	glVertex3f(1.0f, -2.0f, -1.0f);
	glEnd();  // End of drawing color-cube

	// Render a pyramid consists of 4 triangles
	glLoadIdentity();                  // Reset the model-view matrix

	/*bloczek numer 1 end : R| */


	/*bloczek numer 2 start : P| */
	glTranslatef(-3.0f, d2-3, -20.0f);
	glRotatef(th1, 0, 1, 0);
	glBegin(GL_QUADS);                // Begin drawing the color cube with 6 quads
	// Top face (y = 1.0f)
	// Define vertices in counter-clockwise (CCW) order with normal pointing out
	glColor3f(0.0f, 1.0f, 0.0f);     // Green 
	glVertex3f(0.5f, 2.0f, -0.5f);
	glVertex3f(-0.5f, 2.0f, -0.5f);
	glVertex3f(-0.5f, 2.0f, 0.5f);
	glVertex3f(0.5f, 2.0f, 0.5f);

	// Bottom face (y = -1.0f)
	glColor3f(1.0f, 0.5f, 0.0f);     // Orange
	glVertex3f(0.5f, -2.0f, 0.5f);
	glVertex3f(-0.5f, -2.0f, 0.5f);
	glVertex3f(-0.5f, -2.0f, -0.5f);
	glVertex3f(0.5f, -2.0f, -0.5f);

	// Front face  (z = 1.0f)
	glColor3f(1.0f, 1.0f, 0.0f);     // Red -> yellow
	glVertex3f(0.5f, 2.0f, 0.5f);
	glVertex3f(-0.5f, 2.0f, 0.5f);
	glVertex3f(-0.5f, -2.0f, 0.5f);
	glVertex3f(0.5f, -2.0f, 0.5f);

	// Back face (z = -1.0f)
	glColor3f(0.0f, 0.0f, 1.0f);     // Yellow -> blue
	glVertex3f(0.5f, -2.0f, -0.5f);
	glVertex3f(-0.5f, -2.0f, -0.5f);
	glVertex3f(-0.5f, 2.0f, -0.5f);
	glVertex3f(0.5f, 2.0f, -0.5f);

	// Left face (x = -1.0f)
	glColor3f(1.0f, 0.0f, 1.0f);     // Blue -> magneta
	glVertex3f(-0.5f, 2.0f, 0.5f);
	glVertex3f(-0.5f, 2.0f, -0.5f);
	glVertex3f(-0.5f, -2.0f, -0.5f);
	glVertex3f(-0.5f, -2.0f, 0.5f);

	// Right face (x = 1.0f)
	glColor3f(1.0f, 0.0f, 0.0f);     // Magenta -> RED
	glVertex3f(0.5f, 2.0f, -0.5f);
	glVertex3f(0.5f, 2.0f, 0.5f);
	glVertex3f(0.5f, -2.0f, 0.5f);
	glVertex3f(0.5f, -2.0f, -0.5f);
	glEnd();  // End of drawing color-cube

	// Render a pyramid consists of 4 triangles
	glLoadIdentity();
	/*!!!!!!!!!!!!!!!END    bloczek numer 2 end : P| */


	/*!!!!!!!!!!!!!!!STARTbloczek numer 3 start : R- */
	glTranslatef(-2.5f, d2-0.5, -20.0f);
	glRotatef(th1, 0, 1, 0);
	glRotatef((float)th3, 0.0f, 0.0f, 1.0f);
	glBegin(GL_QUADS);                // Begin drawing the color cube with 6 quads
	// Top face (y = 1.0f)
	// Define vertices in counter-clockwise (CCW) order with normal pointing out
	glColor3f(0.0f, 1.0f, 0.0f);     // Green

	glVertex3f(6.0f, 0.5f, -0.5f);
	glVertex3f(-0.5f, 0.5f, -0.5f);
	glVertex3f(-0.5f, 0.5f, 0.5f);
	glVertex3f(6.0f, 0.5f, 0.5f);


	// Bottom face (y = -1.0f)
	glColor3f(1.0f, 0.5f, 0.0f);     // Orange

	glVertex3f(6.0f, -0.5f, 0.5f);
	glVertex3f(-0.5f, -0.5f, 0.5f);
	glVertex3f(-0.5f, -0.5f, -0.5f);
	glVertex3f(6.0f, -0.5f, -0.5f);


	// Front face  (z = 1.0f)
	glColor3f(1.0f, 0.0f, 0.0f);     // Red

	glVertex3f(6.0f, 0.5f, 0.5f);
	glVertex3f(-0.5f, 0.5f, 0.5f);
	glVertex3f(-0.5f, -0.5f, 0.5f);
	glVertex3f(6.0f, -0.5f, 0.5f);


	// Back face (z = -1.0f)
	glColor3f(1.0f, 1.0f, 0.0f);     // Yellow

	glVertex3f(6.0f, -0.5f, -0.5f);
	glVertex3f(-0.5f, -0.5f, -0.5f);
	glVertex3f(-0.5f, 0.5f, -0.5f);
	glVertex3f(6.0f, 0.5f, -0.5f);


	// Left face (x = -1.0f)
	glColor3f(0.0f, 0.0f, 1.0f);     // Blue

	glVertex3f(-0.5f, 0.5f, 0.5f);
	glVertex3f(-0.5f, 0.5f, -0.5f);
	glVertex3f(-0.5f, -0.5f, -0.5f);
	glVertex3f(-0.5f, -0.5f, 0.5f);


	// Right face (x = 1.0f)
	glColor3f(1.0f, 0.0f, 1.0f);     // Magenta

	glVertex3f(6.0f, 0.5f, -0.5f);
	glVertex3f(6.0f, 0.5f, 0.5f);
	glVertex3f(6.0f, -0.5f, 0.5f);
	glVertex3f(6.0f, -0.5f, -0.5f);
	glEnd();  // End of drawing color-cube

	/*bloczek numer 3 end : R- */

	glutSwapBuffers();  // Swap the front and back frame buffers (double buffering)
}

/* Handler for window re-size event. Called back when the window first appears and
whenever the window is re-sized with its new width and height */
void reshape(GLsizei width, GLsizei height) {  // GLsizei for non-negative integer
	// Compute aspect ratio of the new window
	if (height == 0) height = 1;                // To prevent divide by 0
	GLfloat aspect = (GLfloat)width / (GLfloat)height;

	// Set the viewport to cover the new window
	glViewport(0, 0, width, height);

	// Set the aspect ratio of the clipping volume to match the viewport
	glMatrixMode(GL_PROJECTION);  // To operate on the Projection matrix
	glLoadIdentity();             // Reset
	// Enable perspective projection with fovy, aspect, zNear and zFar
	gluPerspective(45.0f, aspect, 0.1f, 100.0f);
}

/* Main function: GLUT runs as a console application starting at main() */
int main(int argc, char** argv) {
	glutInit(&argc, argv);            // Initialize GLUT
	glutInitDisplayMode(GLUT_DOUBLE); // Enable double buffered mode
	glutInitWindowSize(640, 480);   // Set the window's initial width & height
	glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
	glutCreateWindow(title);          // Create window with the given title
	glutDisplayFunc(display);       // Register callback handler for window re-paint event
	glutReshapeFunc(reshape);       // Register callback handler for window re-size event
	glutIdleFunc(idle);
	initGL();                       // Our own OpenGL initialization
	glutMainLoop();                 // Enter the infinite event-processing loop
	return 0;
}

 

1 odpowiedź

0 głosów
odpowiedź 14 stycznia 2019 przez obl Maniak (51,280 p.)
Używasz funkcji do obracania, a wiesz jak działa matematyczny mechanizm obrotu?

                      | 1         0          0 |         |cos(az) -sin(az) 0 |    | Vx|

Mx * Mz * V = |0 cos(ax) -sin(ax) |   *    | sin(az) cos(az) 0 |  *  |Vy|

                     |0  sin(ax)  cos(ax) |          | 0         0         1 |     |Vz|

Kolejność ma znaczenie, w powyższym przypadku najpierw mnożysz wektor przez macierz obrotu względem osi z a później przez macierz obrotu względem osi x. Użyj funkcji obrotu najpierw dla osi x a później dla osi z nie znam się na opengl-u ale powinno zadziałać.
komentarz 14 stycznia 2019 przez heros22pt Użytkownik (950 p.)
niestety to nie ma wpływu na "środek obrotu" :/
komentarz 14 stycznia 2019 przez obl Maniak (51,280 p.)
To najpierw musisz przemieścić ramię żeby środek obrotu znalazł się w początku układu współrzędnych a później po obrocie z powrotem przemieścić obiekt.
komentarz 15 stycznia 2019 przez heros22pt Użytkownik (950 p.)
Skończyłem robotykę, znam zasady translacji i transformacji. To nie rozwiązało problemu, na szczęście udało mi się później znaleźć błąd -> bardzo prosty -> bloczek 3. był przesunięty o 2.5 jednostki zamiast 3 w osi x. Ale bardzo dziękuję za pomoc :) pozdrawiam :)

Podobne pytania

0 głosów
2 odpowiedzi 269 wizyt
pytanie zadane 11 kwietnia 2022 w OpenGL, Unity przez letmestay Użytkownik (520 p.)
0 głosów
1 odpowiedź 178 wizyt
pytanie zadane 6 czerwca 2020 w OpenGL, Unity przez siemaziom Nowicjusz (160 p.)
0 głosów
0 odpowiedzi 175 wizyt

92,551 zapytań

141,393 odpowiedzi

319,522 komentarzy

61,936 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...