#include <stdio.h> #include <math.h> #include <GL/gl.h> #include <GL/glu.h> #include "poly.h" #include <vector> #include <string> using namespace std; Poly::Poly() { position = new Vec(0,0,0); rotation = new Vec(0,0,0); color = new Color(1,0,0); setCenter(Vec(0,0,0)); } Poly::Poly(std::vector<Vec*> & _points) { Poly(_points, Color(1,0,0)); } Poly::Poly(std::vector<Vec*> & _points, Color _color) { position = new Vec(0,0,0); rotation = new Vec(0,0,0); color = _color.clone(); for (std::vector<Vec*>::size_type i = 0 ; i < _points.size(); i++ ) { addPoint(_points.at(i)); } setCenter(calcCenter()); } Poly::~Poly() { delete position; delete rotation; delete color; } /* * set the position where the (rotation-)center of * the polygon is located */ void Poly::setCenter(Vec c) { position = c.clone(); } /* * initial rotation relative to rotation center */ Vec Poly::getInitRotation(Vec& v) { return Vec(atan2(v.y(), v.z()), atan2(v.x(), v.z()), atan2(v.y(), v.x())); } /* * calculate the center relative to all vertices. */ Vec Poly::calcCenter() { Vec s (0,0,0); if ( initpoints.size() == 0 ) { return s; } for ( std::vector<Vec*>::size_type i = 0; i < initpoints.size(); i++ ) { s = s + *(initpoints.at(i)); } return s / (float)initpoints.size(); } /* * reset the position of all vertices (ie. translate your * polygon to an absolute position) */ void Poly::setPosition(Vec newcenter) { Vec diff = newcenter - (*position); delete position; position = newcenter.clone(); for ( std::vector<Vec*>::size_type i = 0; i < initpoints.size(); i++ ) { initpoints.at(i)->add(diff); } } //additional rotation in arcs void Poly::rotate(Vec rot) { rotation->add(rot); } Vec Poly::rotate_x(Vec& c) { Vec initrot = getInitRotation(c); Vec rot = initrot + *rotation; float r = Vec(0, c.y(), c.z()).length(); return Vec (c.x(), r*cos(rot.x()), r*sin(rot.x())); } Vec Poly::rotate_y(Vec& c) { Vec initrot = getInitRotation(c); Vec rot = initrot + *rotation; float r = Vec(c.x(), 0, c.z()).length(); return Vec (r*sin(rot.y()), c.y(), r*cos(rot.y())); } Vec Poly::rotate_z(Vec& c) { Vec initrot = getInitRotation(c); Vec rot = initrot + *rotation; float r = Vec(c.x(), c.y(), 0).length(); return Vec (r*cos(rot.z()), r*sin(rot.z()), c.z()); } Vec Poly::rotate_xyz(Vec out) { Vec ret = rotate_x(out); ret = rotate_y(ret); ret = rotate_z(ret); return ret; } void Poly::draw() { unsigned int vcount = initpoints.size(); glBegin (GL_POLYGON); for ( std::vector<Vec*>::size_type i = 0; i < vcount; i++ ) { Vec cur = rotate_xyz(*initpoints.at(i) - *position); //normal Vec prev = rotate_xyz(*initpoints.at((i-1+vcount)%vcount) - *position); Vec next = rotate_xyz(*initpoints.at((i+1) % vcount) - *position); prev = prev - cur; next = next - cur; glNormal3fv(prev.cross(next).normalize().c); color->drawColor(); glVertex3fv((*position + cur).c); } glEnd(); } int Poly::numPoints() { return (int)initpoints.size(); } void Poly::vardump(std::string whitespace) { printf("%sPoly(%d points, center: [%f, %f, %f], rotation: [%f, %f, %f], color: [%f, %f, %f])\n", whitespace.c_str(), initpoints.size(), position->x(), position->y(), position->z(), rotation->x(), rotation->y(), rotation->z(), color->r, color->g, color->b ); for (std::vector<Vec*>::size_type i = 0 ; i < initpoints.size(); i++ ) { initpoints.at(i)->vardump(whitespace+" "); } } void Poly::addPoint(Vec* p) { p->registerFace(this); initpoints.push_back(p); } void Poly::setColor(Color c) { color = c.clone(); } Color* Poly::getColor() { return color; }