Commit ed3f4107 authored by Taddeüs Kroes's avatar Taddeüs Kroes

Graphics: Added assignment 3.

parent 9fd61674
CC=gcc
WARNING_FLAGS=-Wall -Wextra -Werror-implicit-function-declaration -Wshadow -Wstrict-prototypes -pedantic-errors
CFLAGS=-g -O2 -std=c99 $(WARNING_FLAGS)
LDFLAGS=-g -lGL -lglut -lGLU
.c.o:
$(CC) -c $(CFLAGS) $<
all: transformations gimbal
transformations: main.o transformations.o
$(CC) $(LDFLAGS) -o transformations main.o transformations.o
gimbal: gimbal.o
$(CC) $(LDFLAGS) -o gimbal gimbal.o
clean:
rm -f *.o
rm -f transformations
rm -f gimbal
transformations.o : transformations.h
transformations.o : transformations.h transformations.c
gimbal.o : transformations.h gimbal.c
main.o : transformations.h main.c
/* Computer Graphics, Assignment, Translations, Rotations and Scaling
*
* Filename ........ gimbal.c
* Description ..... Draw teapots that can be interactively rotated with the mouse
* Date ............ 19-08-2008
* Created by ...... Paul Melis
*
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129
* Date ............ 22.09.2010
*/
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "transformations.h"
#include <math.h>
#define ROTATE_X_AND_Z 0
#define ROTATE_ONLY_X 1
#define ROTATE_ONLY_Z 2
int window;
float x_rotation=0.0, z_rotation=0.0;
int prev_mouse_x, prev_mouse_y;
int do_mouse_transform=0;
int rotation_mode=ROTATE_X_AND_Z;
void InitGL(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
}
void ReSizeGLScene(int Width, int Height)
{
float hfov=90.0, vfov;
if (Height == 0)
Height=1;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
vfov = hfov / (1.0*Width/Height);
gluPerspective(vfov, (GLfloat)Width/(GLfloat)Height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
void drawRotatedTeapot(float rotx, float roty, float rotz)
{
glRotatef(rotx, 1.0, 0.0, 0.0);
glRotatef(roty, 0.0, 1.0, 0.0);
glRotatef(rotz, 0.0, 0.0, 1.0);
// teapot
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glutSolidTeapot(1.0);
// local coordinate axes
glDisable(GL_LIGHTING);
glLineWidth(2.0);
glBegin(GL_LINES);
// Red: X-axis
glColor3f(1, 0, 0);
glVertex3f(0, 0, 0);
glVertex3f(2, 0, 0);
// Green: Y-axis
glColor3f(0, 1, 0);
glVertex3f(0, 0, 0);
glVertex3f(0, 2, 0);
// Blue: Z-axis
glColor3f(0, 0, 1);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 2);
glEnd();
}
void drawTeapots(void)
{
/* This function is called from DrawGLScene() below */
glPushMatrix();
drawRotatedTeapot(x_rotation, 0.0, z_rotation);
glPopMatrix();
glTranslatef(5, 0, 0);
glPushMatrix();
drawRotatedTeapot(x_rotation, 45.0, z_rotation);
glPopMatrix();
glTranslatef(5, 0, 0);
glPushMatrix();
drawRotatedTeapot(x_rotation, 90.0, z_rotation);
glPopMatrix();
}
void DrawGLScene(void)
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glLoadIdentity ();
gluLookAt (5.0, 6.0, 9.0, 5.0, 0.0, 0.0, 0.0, 1.0, 0.0);
drawTeapots();
glutSwapBuffers();
}
void keyPressed(unsigned char key, int x, int y)
{
switch(key) {
case 27:
glutDestroyWindow(window);
exit(0);
case 'r':
x_rotation = 0.0f;
z_rotation = 0.0f;
rotation_mode = ROTATE_X_AND_Z;
printf("X and Z rotation reset to 0 degrees\n");
printf("Mouse rotates around both X and Z axes\n");
break;
case 'x':
rotation_mode = ROTATE_ONLY_X;
printf("Mouse rotates only around X axis\n");
break;
case 'z':
rotation_mode = ROTATE_ONLY_Z;
printf("Mouse rotates only around Z axis\n");
break;
}
DrawGLScene();
}
void mouseClick(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
prev_mouse_x = x;
prev_mouse_y = y;
do_mouse_transform = 1;
}
else
{
// mouse button released
do_mouse_transform = 0;
}
}
}
void mouseMove(int x, int y)
{
int dx, dy;
if (do_mouse_transform)
{
dx = x - prev_mouse_x;
dy = y - prev_mouse_y;
if (rotation_mode != ROTATE_ONLY_Z)
x_rotation += dy * 0.25f;
if (rotation_mode != ROTATE_ONLY_X)
z_rotation -= dx * 0.25f;
prev_mouse_x = x;
prev_mouse_y = y;
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutInitWindowPosition(0, 0);
window = glutCreateWindow("Gimbal lock");
glutDisplayFunc(&DrawGLScene);
glutIdleFunc(&DrawGLScene);
glutReshapeFunc(&ReSizeGLScene);
glutKeyboardFunc(&keyPressed);
glutMouseFunc(&mouseClick);
glutMotionFunc(&mouseMove);
InitGL();
glutMainLoop();
return 1;
}
/* Computer Graphics, Assignment 3, Translations, Rotations and Scaling
*
* Filename ........ main.c
* Description ..... Creates OpenGL window and draws the scene.
* Date ............ 01-09-2006
* Created by ...... Jurgen Sturm
*
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129
* Date ............ 22.09.2010
*/
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "transformations.h"
#include <math.h>
int window;
int useMyTransformations=0;
int frame=0;
int doRotate=1;
int doTranslate=1;
int doScale=1;
double speed=0.005;
void InitGL(int Width, int Height)
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
}
void ReSizeGLScene(int Width, int Height)
{
int xRange = 10, yRange = 10, zRange = 100;
if (Height==0)
Height=1;
glViewport(0, 0, Width, Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/*gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);*/
if (Width <= Height)
glOrtho (-xRange, xRange, -yRange*Height/Width, yRange*Height/Width, -zRange, zRange);
else
glOrtho (-xRange*Width/Height, xRange*Width/Height, -yRange, yRange, -zRange, zRange);
glMatrixMode(GL_MODELVIEW);
}
void drawCube(void) {
glBegin(GL_QUADS); /* start drawing the cube. */
/* top of cube */
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
/* bottom of cube */
glColor3f(1.0f,0.5f,0.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
/* front of cube */
glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
/* back of cube. */
glColor3f(1.0f,1.0f,0.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
/* left of cube */
glColor3f(0.0f,0.0f,1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f,-1.0f);
glVertex3f(-1.0f,-1.0f, 1.0f);
/* Right of cube */
glColor3f(1.0f,0.0f,1.0f);
glVertex3f( 1.0f, 1.0f,-1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f, 1.0f);
glVertex3f( 1.0f,-1.0f,-1.0f);
glEnd();
}
void drawTeapot(void)
{
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glutSolidTeapot(2.0);
}
void DrawGLScene(void)
{
double stretch,height,position,rotation;
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(5.0, 5.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
position=cos((double)frame*speed)*2;
height=fabs(sin((double)frame*speed)*10)+1;
rotation=cos((double)frame*speed)*90;
stretch=1+0.3*sin((double)frame*speed/2);
if(useMyTransformations) {
if(doTranslate) myTranslatef(position,height-5,0.0);
if(doRotate) myRotatef(rotation,0.2,0.6,0.77);
if(doScale) myScalef(1/sqrt(stretch),stretch,1/sqrt(stretch));
} else {
if(doTranslate) glTranslatef(position,height-5,0.0);
if(doRotate) glRotatef(rotation,0.2,0.6,0.77);
if(doScale) glScalef(1/sqrt(stretch),stretch,1/sqrt(stretch));
}
//drawCube();
drawTeapot();
frame++;
glutSwapBuffers();
}
void keyPressed(unsigned char key, int x, int y)
{
switch(key) {
case 27:
case 'q':
glutDestroyWindow(window);
exit(0);
case 'r':
doRotate = !doRotate;
break;
case 't':
doTranslate = !doTranslate;
break;
case 's':
doScale = !doScale;
break;
case '+':
speed *= 1.1;
frame = 0;
break;
case '-':
speed /= 1.1;
frame = 0;
break;
default:
useMyTransformations = !useMyTransformations;
if (useMyTransformations)
glutSetWindowTitle("Your transformations");
else
glutSetWindowTitle("OpenGL transformations");
}
DrawGLScene();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(0, 0);
window = glutCreateWindow("OpenGL transformations");
glutDisplayFunc(&DrawGLScene);
glutIdleFunc(&DrawGLScene);
glutReshapeFunc(&ReSizeGLScene);
glutKeyboardFunc(&keyPressed);
InitGL(640, 480);
glutMainLoop();
return 1;
}
Q1:
gimbal.c, regels 65-67:
glRotatef(rotx, 1.0, 0.0, 0.0);
glRotatef(roty, 0.0, 1.0, 0.0);
glRotatef(rotz, 0.0, 0.0, 1.0);
Eerst wordt de x-as geroteerd, vervolgens de y-as en teslotte de x-as.
Q2:
We zien dat de draaiing die plaatsvindt door de cursor verticaal te bewegen
gelijk is aan de draaiing die plaatsvindt door de cursor horizontaal te bewegen.
Dit komt doordat de rotatieassen die corresponderen met deze bewegingen overlappen,
dit is een gevolg van de volgorde van de rotaties.
Als we bijvoorbeeld de code veranderen naar...
glRotatef(rotx, 1.0, 0.0, 0.0);
glRotatef(rotz, 0.0, 0.0, 1.0);
glRotatef(roty, 0.0, 1.0, 0.0);
...zien we dat de assen niet meer samenvallen en dat de cursorbeweging het effect
heeft dat we verwachten.
/* Computer Graphics, Assignment, Translations, Rotations and Scaling
*
* Filename ........ transformations.c
* Description ..... Contains the re-programmed translation, rotation and scaling functions
* Date ............ 27-08-2009
*
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129
* Date ............ 22.09.2010
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/gl.h>
#include "transformations.h"
#include "vectors.h"
/* ANSI C/ISO C89 does not specify this constant (?) */
#ifndef M_PI
#define M_PI 3.14159265358979323846 /* pi */
#endif
void myScalef(GLfloat x, GLfloat y, GLfloat z)
{
GLfloat M[16] =
{
x, 0.0, 0.0, 0.0,
0.0, y, 0.0, 0.0,
0.0, 0.0, z, 0.0,
0.0, 0.0, 0.0, 1.0
};
glMultMatrixf(M);
}
void myTranslatef(GLfloat x, GLfloat y, GLfloat z)
{
GLfloat M[16] =
{
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0
};
glMultMatrixf(M);
}
void myRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
//GLfloat u[3], v[3], w[3], t[3];
vector u, v, w, t;
//
// 1. Create the orthonormal basis
//
// Store the incoming rotation axis in w and normalize w
w = normalizeVector(createVector(x, y, z));
// Compute the value of t, based on w
t = w;
if( t.x < t.y )
{
if( t.x < t.z )
t.x = 1;
else
t.z = 1;
}
else
{
if( t.y < t.z )
t.y = 1;
else
t.z = 1;
}
// Compute u = t x w
u = crossProduct(t, w);
// Normalize u
u = normalizeVector(u);
// Compute v = w x u
v = crossProduct(w, u);
// At this point u, v and w should form an orthonormal basis.
// If your routine does not seem to work correctly it might be
// a good idea to the check the vector values.
//
// 2. Set up the three matrices making up the rotation
//
// Specify matrix A
GLfloat A[16] =
{
u.x, u.y, u.z, 0.0,
v.x, v.y, v.z, 0.0,
w.x, w.y, w.z, 0.0,
0.0, 0.0, 0.0, 1.0
};
// Convert 'angle' to radians
angle = angle * M_PI / 180;
// Specify matrix B
GLfloat B[16] =
{
cosf(angle), sinf(angle), 0.0, 0.0,
-sinf(angle), cosf(angle), 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
// Specify matrix C
GLfloat C[16] =
{
u.x, v.x, w.x, 0.0,
u.y, v.y, w.y, 0.0,
u.z, v.z, w.z, 0.0,
0.0, 0.0, 0.0, 1.0
};
//
// 3. Apply the matrices to get the combined rotation
//
glMultMatrixf(A);
glMultMatrixf(B);
glMultMatrixf(C);
}
/*
* Some help functions to calculate with vectors
*/
vector createVector(GLfloat x, GLfloat y, GLfloat z)
{
vector p = {x, y, z};
return p;
}
vector normalizeVector(vector p)
{
return scalarMultiply(p, 1 / VECTOR_LENGTH(p));
}
vector scalarMultiply(vector p, GLfloat scalar)
{
return createVector(p.x * scalar, p.y * scalar, p.z * scalar);
}
GLfloat dotProduct(vector p1, vector p2)
{
return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;
}
vector crossProduct(vector p1, vector p2)
{
return createVector( p1.y * p2.z - p1.z * p2.y,
p1.z * p2.x - p1.x * p2.z,
p1.x * p2.y - p1.y * p2.x );
}
/* Computer Graphics, Assignment, Translations, Rotations and Scaling
*
* Filename ........ transformations.h
* Description ..... Contains the re-programmed translation, rotation and scaling functions
* Date ............ 19-08-2008
*
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129
* Date ............ 22.09.2010
*/
#ifndef TRANSFORMATIONS_H
#define TRANSFORMATIONS_H
void myScalef(GLfloat x, GLfloat y, GLfloat z);
void myTranslatef(GLfloat x, GLfloat y, GLfloat z);
void myRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
#endif
/* Computer Graphics, Assignment, Intersections
* Filename ........ vectors.c
* Description ..... Vector calculation help functions.
* Date ............ 22.09.2010
*
* Student name .... Sander van Veen & Taddeus Kroes
* Student email ... sandervv@gmail.com & taddeuskroes@hotmail.com
* Collegekaart .... 6167969 & 6054129
* Date ............ 22.09.2010
*/
#ifndef VECTORS_H
#define VECTORS_H
#define VECTOR_LENGTH(p) sqrt( p.x*p.x + p.y*p.y + p.z*p.z )
typedef struct vector
{
GLfloat x, y, z;
}
vector;
vector createVector(GLfloat x, GLfloat y, GLfloat z);
vector normalizeVector(vector p);
vector addVectors(vector p1, vector p2);
vector substractVectors(vector p1, vector p2);
vector scalarMultiply(vector p, GLfloat scalar);
GLfloat dotProduct(vector p1, vector p2);
vector crossProduct(vector p1, vector p2);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment