#include "glumodel.h" #include <string> #include <GL/gl.h> // This file import the OpenGL interface #include <GL/glu.h> // This file offers some OpenGL-related utilities #include <math.h> GenericModel::GenericModel() { init(Vec(0,0,0), Material()); } GenericModel::GenericModel(Vec _pos, Material _mat) { init(_pos, _mat); } void GenericModel::init(Vec _pos, Material _mat) { pos = _pos.clone(); rot = new Vec(0,0,0); scale = 1; mat = _mat.clone(); pt = gluNewQuadric(); visible = true; } void GenericModel::hide ( ) { visible = false; } void GenericModel::show ( ) { visible = true; } void GenericModel::setColor(Color* c) { Color sp = *(mat->specular->clone()); delete mat; mat = new Material(*(c->clone()), sp); } void GenericModel::translate ( Vec d ) { pos->add((Vec)d); } void GenericModel::rotate ( Vec r ) { rot->add((Vec)r); } GluSphere::GluSphere() { init(Vec(0,0,0), Material(Color(1,0,1)), 10); } GluSphere::GluSphere(Vec _pos, Material _mat, float _rad) { init(_pos, _mat, _rad); } void GluSphere::init(Vec _pos, Material _mat, float _rad) { GenericModel::init(_pos, _mat); rad = _rad; } void GluSphere::draw() { if ( visible ) { glPushMatrix(); glRotatef(rot->x(), 1.0f, 0.0f, 0.0f); glRotatef(rot->y(), 0.0f, 1.0f, 0.0f); glRotatef(rot->z(), 0.0f, 0.0f, 1.0f); glTranslatef(pos->x(), pos->y(), pos->z()); mat->draw(); gluSphere(gluNewQuadric(), rad, 300, 300); glPopMatrix(); } } Fractal::Fractal() { init(Vec(0,0,0), Material(), 4, 30); } void Fractal::init(Vec _pos, Material _m, int _iters, float _len) { GenericModel::init(_pos, _m); iters = _iters; pos = _pos.clone(); len = _len; } void Fractal::setIterations(int _iters) { iters = _iters; } SierpinskiPyramid::SierpinskiPyramid(Vec _pos, int _iters, float _len) { Fractal::init(_pos, Material(), _iters, _len); rot = new Vec(0,0,0); buildList(); } void SierpinskiPyramid::buildList() { list = glGenLists(1); glNewList(list, GL_COMPILE); drawPyramid(); glEndList(); } void SierpinskiPyramid::construct(int n) { if ( n > 0 ) { n--; glPushMatrix(); glScalef(0.5, 0.5, 0.5); construct(n); glPopMatrix(); glPushMatrix(); glScalef(0.5, 0.5, 0.5); glTranslatef(1, 0, 0.5); construct(n); glPopMatrix(); glPushMatrix(); glScalef(0.5, 0.5, 0.5); glTranslatef(0, 0, 1); construct(n); glPopMatrix(); glPushMatrix(); glScalef(0.5, 0.5, 0.5); glTranslatef(0.5, 1, 0.5); construct(n); glPopMatrix(); } else { /* if available, use OpenGL lists to accelerate drawing */ if ( list == 0 ) { drawPyramid(); } else { glCallList(list); } } } void SierpinskiPyramid::drawPyramid() { Vec a; Vec b; Vec p0 = Vec(0,0,0); Vec p1 = Vec(1,0,0.5); Vec p2 = Vec(0,0,1); Vec p3 = Vec(0.5,1,0.5); glBegin(GL_TRIANGLES); a = (p0)-(p1); b = (p2)-(p1); glNormal3fv((a.cross(b)).c); glVertex3fv(p0.c); glVertex3fv(p1.c); glVertex3fv(p2.c); a = (p3)-(p1); b = (p0)-(p1); glNormal3fv((a.cross(b)).c); glVertex3fv(p3.c); glVertex3fv(p1.c); glVertex3fv(p0.c); a = (p0)-(p2); b = (p3)-(p2); glNormal3fv((a.cross(b)).c); glVertex3fv(p0.c); glVertex3fv(p2.c); glVertex3fv(p3.c); a = (p2)-(p1); b = (p3)-(p1); glNormal3fv((a.cross(b)).c); glVertex3fv(p2.c); glVertex3fv(p1.c); glVertex3fv(p3.c); glEnd(); } void SierpinskiPyramid::draw() { if ( visible ) { glPushMatrix(); /* rotate SierpinskiPyramid */ glRotatef(rot->x(), 1.0f, 0.0f, 0.0f); glRotatef(rot->y(), 0.0f, 1.0f, 0.0f); glRotatef(rot->z(), 0.0f, 0.0f, 1.0f); /* move it to the desired position */ glTranslatef(pos->x(), pos->y(), pos->z()); /* scale it to the desired length, width and height */ glScalef(len, len, len); /* draw material */ mat->draw(); /* draw it */ construct(iters); glPopMatrix(); } } SierpinskiPyramid::~SierpinskiPyramid ( ) { } KochFractal::KochFractal(Vec _pos, int _iters, float _len) { Fractal::init(_pos, Material(), _iters, _len); setIterations(_iters); multiplicity = 6; mult_angle = 60; } void KochFractal::setIterations(int _iters) { Fractal::setIterations(_iters) ; mylen = len / pow(3, iters); } void KochFractal::draw() { if ( visible ) { //TODO: move draw function to Fractal class, it's common for all //inheriting fractals.... glPushMatrix(); /* rotate */ glRotatef(rot->x(), 1.0f, 0.0f, 0.0f); glRotatef(rot->y(), 0.0f, 1.0f, 0.0f); glRotatef(rot->z(), 0.0f, 0.0f, 1.0f); /* move it to the desired position */ glTranslatef(pos->x(), pos->y(), pos->z()); for (int i = 0; i < multiplicity; i++) { iter(iters); glRotatef(mult_angle, 1,0,0); } glPopMatrix(); } } void KochFractal::iter(float nbit) { float n = nbit - 1; if (n >= 0) { iter(n); glRotatef(60,1,0,0); iter(n); glRotatef(-120,1,0,0); iter(n); glRotatef(60,1,0,0); iter(n); } else { glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,mylen,0); glEnd(); glTranslatef(0,mylen,0); } }