#include #include #include "vector3d.h" #include "vector4d.h" #include "matrix4x4.h" #include #define M_PI 3.14 using namespace std; /* Global variables */ char title[] = "Konusni zupcanik"; Vector3D camera(6.0, 6.0, 6.0); //Vector3D camera(0.01, 5.0, 0.01); int FPS = 60; double WINDOW_HEIGHT = 480; double aspectRatio = 640.0f / 480.0f; Vector3D N(0.7, 0.2, 0.1); Vector3D centar(0.2, 0.5, 0.2); vector> base0; vector> base1; double k = 3.7; double r = 1.6; double R = 2.5; double l = 3.5; double phi_konus = 40; int n_zupcanika = 20; vector createCircle(double r, int n) { double phi = 360.0 / n; Vector3D radius(r, 0, 0); vector circle; Vector3D centar(0.0, 0.0, 0.0); circle.push_back(radius); for (int i = 0; i < n; i++) { Vector3D v = Matrix4x4::Rotate(circle[i], centar, 2, M_PI / 180.0 * phi); circle.push_back(v); } return circle; } vector> createBase(double r, double R, double l, double n, int baseIndex) { Vector3D centar(0.0, 0.0, 0.0); vector circle1 = createCircle(r, n); vector circle2 = Matrix4x4::Rotate(circle1, centar, 2, M_PI / 180.0 * 360.0 / n / 5.0); vector base1; for (int i = 0; i < n; i++) { base1.push_back(circle1[i]); base1.push_back(circle2[i]); } vector circle3 = createCircle(R, n); vector circle4 = Matrix4x4::Rotate(circle3, centar, 2, M_PI / 180.0 * 360.0 / n / 5.0); // -------------- vector base2; for (int i = 0; i < n; i++) { base2.push_back(circle3[i]); base2.push_back(circle4[i]); } //------------------ vector circle5 = createCircle(l, n); vector circle6 = Matrix4x4::Rotate(circle5, centar, 2, M_PI / 180.0 * 360.0 / n / 5.0/2.0); circle5 = Matrix4x4::Rotate(circle5, centar, 2, 0.5 * (M_PI / 180.0 * 360.0 / n)); circle6 = Matrix4x4::Rotate(circle6, centar, 2, 0.5 * (M_PI / 180.0 * 360.0 / n)); vector base3; for (int i = 0; i < n; i++) { base3.push_back(circle5[i]); base3.push_back(circle6[i]); } vector> base; base.push_back(base1); base.push_back(base2); if (baseIndex > 0) { base.push_back(base2); } base.push_back(base3); return base; } void drawBase(vector> base, int baseIndex) { glColor3f(0.7, 0.7, 0.7); for (int i = 0; i < base[0].size()-1; i++) { glBegin(GL_POLYGON); glVertex3f(base[0][i].X(), base[0][i].Y(), base[0][i].Z()); glVertex3f(base[1][i].X(), base[1][i].Y(), base[1][i].Z()); glVertex3f(base[1][i+1].X(), base[1][i+1].Y(), base[1][i+1].Z()); glVertex3f(base[0][i + 1].X(), base[0][i + 1].Y(), base[0][i + 1].Z()); glEnd(); } int n = base[0].size() - 1; glBegin(GL_POLYGON); glVertex3f(base[0][n].X(), base[0][n].Y(), base[0][n].Z()); glVertex3f(base[1][n].X(), base[1][n].Y(), base[1][n].Z()); glVertex3f(base[1][0].X(), base[1][0].Y(), base[1][0].Z()); glVertex3f(base[0][0].X(), base[0][0].Y(), base[0][0].Z()); glEnd(); glColor3f(0.6, 0.6, 0.6); for (int i = 0; i < base[0].size() - 2; i+=2) { glBegin(GL_POLYGON); glVertex3f(base[1 + baseIndex][i+1].X(), base[1 + baseIndex][i+1].Y(), base[1 + baseIndex][i+1].Z()); glVertex3f(base[2 + baseIndex][i].X(), base[2 + baseIndex][i].Y(), base[2 + baseIndex][i].Z()); glVertex3f(base[2 + baseIndex][i + 1].X(), base[2 + baseIndex][i + 1].Y(), base[2 + baseIndex][i + 1].Z()); glVertex3f(base[1 + baseIndex][i + 2].X(), base[1 + baseIndex][i + 2].Y(), base[1 + baseIndex][i + 2].Z()); glEnd(); } glBegin(GL_POLYGON); glVertex3f(base[1 + baseIndex][n].X(), base[1 + baseIndex][n].Y(), base[1 + baseIndex][n].Z()); glVertex3f(base[2 + baseIndex][n-1].X(), base[2 + baseIndex][n-1].Y(), base[2 + baseIndex][n-1].Z()); glVertex3f(base[2 + baseIndex][n].X(), base[2 + baseIndex][n].Y(), base[2 + baseIndex][n].Z()); glVertex3f(base[1 + baseIndex][0].X(), base[1 + baseIndex][0].Y(), base[1 + baseIndex][0].Z()); glEnd(); if (baseIndex > 0) { for (int i = 0; i < base[0].size() - 1; i++) { glBegin(GL_POLYGON); glVertex3f(base[1][i].X(), base[1][i].Y(), base[1][i].Z()); glVertex3f(base[2][i].X(), base[2][i].Y(), base[2][i].Z()); glVertex3f(base[2][i + 1].X(), base[2][i + 1].Y(), base[2][i + 1].Z()); glVertex3f(base[1][i + 1].X(), base[1][i + 1].Y(), base[1][i + 1].Z()); glEnd(); } glBegin(GL_POLYGON); glVertex3f(base[1][n].X(), base[1][n].Y(), base[1][n].Z()); glVertex3f(base[2][n].X(), base[2][n].Y(), base[2][n].Z()); glVertex3f(base[2][0].X(), base[2][0].Y(), base[2][0].Z()); glVertex3f(base[1][0].X(), base[1][0].Y(), base[1][0].Z()); glEnd(); } } void drawSides() { glColor3f(0.9, 0.9, 0.9); // unutrasnonjost for (int i = 0; i < base1[0].size() - 1; i++) { glBegin(GL_POLYGON); glVertex3f(base0[0][i].X(), base0[0][i].Y(), base0[0][i].Z()); glVertex3f(base1[0][i].X(), base1[0][i].Y(), base1[0][i].Z()); glVertex3f(base1[0][i + 1].X(), base1[0][i + 1].Y(), base1[0][i + 1].Z()); glVertex3f(base0[0][i + 1].X(), base0[0][i + 1].Y(), base0[0][i + 1].Z()); glEnd(); } int n = base0[0].size() - 1; glBegin(GL_POLYGON); glVertex3f(base0[0][n].X(), base0[0][n].Y(), base0[0][n].Z()); glVertex3f(base1[0][n].X(), base1[0][n].Y(), base1[0][n].Z()); glVertex3f(base1[0][0].X(), base1[0][0].Y(), base1[0][0].Z()); glVertex3f(base0[0][0].X(), base0[0][0].Y(), base0[0][0].Z()); glEnd(); glColor3f(0.66, 0.66, 0.66); // -------------- unutra for (int i = 0; i < base1[0].size() - 1; i+=2) { glBegin(GL_POLYGON); glVertex3f(base0[1][i].X(), base0[1][i].Y(), base0[1][i].Z()); glVertex3f(base1[2][i].X(), base1[2][i].Y(), base1[2][i].Z()); glVertex3f(base1[2][i + 1].X(), base1[2][i + 1].Y(), base1[2][i + 1].Z()); glVertex3f(base0[1][i + 1].X(), base0[1][i + 1].Y(), base0[1][i + 1].Z()); glEnd(); } glColor3f(0.75, 0.75, 0.75); // jedna strana for (int i = 0; i < base0[0].size() - 2; i += 2) { glBegin(GL_POLYGON); glVertex3f(base0[1][i + 1].X(), base0[1][i + 1].Y(), base0[1][i + 1].Z()); glVertex3f(base1[2][i + 1].X(), base1[2][i + 1].Y(), base1[2][i + 1].Z()); glVertex3f(base1[3][i].X(), base1[3][i].Y(), base1[3][i].Z()); glVertex3f(base0[2][i].X(), base0[2][i].Y(), base0[2][i].Z()); glEnd(); } glBegin(GL_POLYGON); glVertex3f(base0[1][n].X(), base0[1][n].Y(), base0[1][n].Z()); glVertex3f(base1[2][n].X(), base1[2][n].Y(), base1[2][n].Z()); glVertex3f(base1[3][n - 1].X(), base1[3][n - 1].Y(), base1[3][n-1].Z()); glVertex3f(base0[2][n - 1].X(), base0[2][n - 1].Y(), base0[2][n - 1].Z()); glEnd(); // ------------- spoljne glColor3f(0.5, 0.5, 0.5); for (int i = 0; i < base0[0].size() - 2; i += 2) { glBegin(GL_POLYGON); glVertex3f(base1[3][i].X(), base1[3][i].Y(), base1[3][i].Z()); glVertex3f(base0[2][i].X(), base0[2][i].Y(), base0[2][i].Z()); glVertex3f(base0[2][i+1].X(), base0[2][i+1].Y(), base0[2][i+1].Z()); glVertex3f(base1[3][i+1].X(), base1[3][i+1].Y(), base1[3][i+1].Z()); glEnd(); } glBegin(GL_POLYGON); glVertex3f(base1[3][n-1].X(), base1[3][n-1].Y(), base1[3][n-1].Z()); glVertex3f(base0[2][n-1].X(), base0[2][n-1].Y(), base0[2][n-1].Z()); glVertex3f(base0[2][n].X(), base0[2][n].Y(), base0[2][n].Z()); glVertex3f(base1[3][n].X(), base1[3][n].Y(), base1[3][n].Z()); glEnd(); // --- zadnja strana glColor3f(0.55, 0.55, 0.55); for (int i = 0; i < base0[0].size() - 2; i += 2) { glBegin(GL_POLYGON); glVertex3f(base0[2][i + 1].X(), base0[2][i + 1].Y(), base0[2][i + 1].Z()); glVertex3f(base1[3][i + 1].X(), base1[3][i + 1].Y(), base1[3][i + 1].Z()); glVertex3f(base1[2][i + 2].X(), base1[2][i + 2].Y(), base1[2][i + 2].Z()); glVertex3f(base0[1][i + 2].X(), base0[1][i + 2].Y(), base0[1][i + 2].Z()); glEnd(); } glBegin(GL_POLYGON); glVertex3f(base0[2][n].X(), base0[2][n].Y(), base0[2][n].Z()); glVertex3f(base1[3][n].X(), base1[3][n].Y(), base1[3][n].Z()); glVertex3f(base1[2][0].X(), base1[2][0].Y(), base1[2][0].Z()); glVertex3f(base0[1][0].X(), base0[1][0].Y(), base0[1][0].Z()); glEnd(); } void draw_axis() { Vector3D centar(0.0,0.0,0.0); Vector3D osaX(1.0, 0.0, 0.0); Vector3D osaY(0.0, 1.0, 0.0); Vector3D osaZ(0.0, 0.0, 1.0); glColor3f(1.0,0.0,0.0); glBegin(GL_LINES); glVertex3f(centar.X(), centar.Y(), centar.Z()); glVertex3f(2 * osaX.X(), 2 * osaX.Y(), 2 * osaX.Z()); glEnd(); glColor3f(0.0,1.0,0.0); glBegin(GL_LINES); glVertex3f(centar.X(), centar.Y(), centar.Z()); glVertex3f(2 * osaY.X(), 2 * osaY.Y(), 2 * osaY.Z()); glEnd(); glColor3f(0.0,0.0,1.0); glBegin(GL_LINES); glVertex3f(centar.X(), centar.Y(), centar.Z()); glVertex3f(2 * osaZ.X(), 2 * osaZ.Y(), 2 * osaZ.Z()); glEnd(); } void SetCamera() { glViewport(0, 0, WINDOW_HEIGHT*aspectRatio, WINDOW_HEIGHT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(80.0f, aspectRatio, 0.1f, 50.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(camera.m_x, camera.m_y, camera.m_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } void timer(int v) { Matrix4x4 mr; mr = Matrix4x4::CreateRotationMatrix(centar, N, M_PI / 180.0 * 0.5); base0 = mr.Transform(base0); base1 = mr.Transform(base1); //Vector3D CR(0, 0, 0); //camera = Matrix4x4::Rotate(camera, CR , 2, M_PI / 180.0 * 0.5); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(camera.m_x, camera.m_y, camera.m_z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glutTimerFunc(1000 / FPS, timer, v); glutPostRedisplay(); } void initGL() { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling } vector< vector > S; void TransformV1(Matrix4x4& M, vector& v) { for (unsigned int i = 0; i < v.size(); i++) v[i] = M.Transform(v[i]); } void TransformV2(Matrix4x4& M, vector< vector >& v) { for (unsigned int i = 0; i < v.size(); i++) TransformV1(M, v[i]); } void CreateTorus(vector< vector >& torus, double r_inside, double r_outside, int n, int m) { double r1 = 0.5 * (r_inside + r_outside); double r2 = 0.5 * (r_outside - r_inside); torus.resize(n); for (int i = 0; i < n; i++) torus[i].resize(m); Matrix4x4 MRotate1, MRotate2, MT1, MT2, M; MRotate1.loadRotateY(2.0 * M_PI / n); MT1.loadTranslate(-r1, 0.0, 0.0); MRotate2.loadRotateZ(2.0 * M_PI / m); MT2.loadTranslate(r1, 0.0, 0.0); M = MT2 * MRotate2 * MT1; torus[0][0] = Vector3D(r1 + r2, 0.0, 0.0); for (int i = 1; i < m; i++) torus[0][i] = M.Transform(torus[0][i - 1]); for (int i = 1; i < n; i++) { torus[i] = torus[i - 1]; TransformV1(MRotate1, torus[i]); } } void DrawPolygon(vector& polygon) { //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBegin(GL_POLYGON); for (unsigned int i = 0; i < polygon.size(); i++) glVertex3d(polygon[i].m_x, polygon[i].m_y, polygon[i].m_z); glEnd(); } void kreirajKrug(vector& K, double r, int n) { K.resize(n); K[0] = Vector3D(r, 0, 0); double alpha = 2.0 * M_PI / n; double ugao = alpha; for (int i = 0; i < n; i++) { K[i] = Vector3D(r * cos(ugao), r * sin(ugao), 0); ugao += alpha; } } void kreirajStrelicu(vector>& S, double r1, double r2, double r3, double d1, double d2, double d3, double d4, double d5, double alpha, double beta, int n) { S.resize(12); // S[0].resize(1); S[0][0] = Vector3D(0, 0, -d1); kreirajKrug(S[1], r1, n); // kreirajKrug(S[2], r1, n); Matrix4x4 MT; MT.loadTranslate(0, 0, d2); TransformV1(MT, S[2]); kreirajKrug(S[3], r2, n); MT.loadTranslate(0, 0, d2 + d3); TransformV1(MT, S[3]); kreirajKrug(S[4], r2, n); MT.loadTranslate(0, 0, d2 + d3 + d4); TransformV1(MT, S[4]); kreirajKrug(S[5], r3, n); MT.loadTranslate(0, 0, d2 + d3 + d4 + d3); TransformV1(MT, S[5]); kreirajKrug(S[6], r3, n); MT.loadTranslate(0, 0, d2 + d3 + d4 + d3 + d4); TransformV1(MT, S[6]); S[7].resize(1); S[7][0] = Vector3D(0, 0, d2 + d3 + d4 + d3 + d4 + d1); S[8].resize(4); S[8][0] = Vector3D(0, 0, 0); S[8][1] = Vector3D(0, 0, d4); double h = (d4 - d5) / (1 + 1.0 / tan(beta)); S[8][2] = Vector3D(0, h, d4 - h / tan(beta)); S[8][3] = Vector3D(0, h, d4 - h / tan(beta) - d5); TransformV1(MT, S[8]); Matrix4x4 MRZ; double a = M_PI / 2.0; double ugao = a; MRZ.loadRotateZ(ugao); for (int i = 0; i < 3; i++) { MRZ.loadRotateZ(ugao); S[9 + i] = S[8]; TransformV1(MRZ, S[9 + i]); ugao += a; } Matrix4x4 MTS; MTS.loadTranslate(0, 0, -(d2 + d3 + d4 + d3 + d4) / 2.0); TransformV2(MTS, S); } void nacrtajStralicu(vector >& S, int n) { vector p; p.resize(4); p[0] = S[0][0]; for (int i = 0; i < n - 1; i++) { p[1] = S[1][i]; p[2] = S[1][i + 1]; DrawPolygon(p); } p[1] = S[1][n - 1]; p[2] = S[1][0]; DrawPolygon(p); // for (int i = 0; i < n - 1; i++) { p[0] = S[1][i]; p[1] = S[2][i]; p[2] = S[2][i + 1]; p[3] = S[1][i + 1]; DrawPolygon(p); } p[0] = S[1][n - 1]; p[1] = S[2][n - 1]; p[2] = S[2][0]; p[3] = S[1][0]; DrawPolygon(p); // for (int i = 0; i < n - 1; i++) { p[0] = S[2][i]; p[1] = S[3][i]; p[2] = S[3][i + 1]; p[3] = S[2][i + 1]; DrawPolygon(p); } p[0] = S[2][n - 1]; p[1] = S[3][n - 1]; p[2] = S[3][0]; p[3] = S[2][0]; DrawPolygon(p); // for (int i = 0; i < n - 1; i++) { p[0] = S[3][i]; p[1] = S[4][i]; p[2] = S[4][i + 1]; p[3] = S[3][i + 1]; DrawPolygon(p); } p[0] = S[3][n - 1]; p[1] = S[4][n - 1]; p[2] = S[4][0]; p[3] = S[3][0]; DrawPolygon(p); // for (int i = 0; i < n - 1; i++) { p[0] = S[4][i]; p[1] = S[5][i]; p[2] = S[5][i + 1]; p[3] = S[4][i + 1]; DrawPolygon(p); } p[0] = S[4][n - 1]; p[1] = S[5][n - 1]; p[2] = S[5][0]; p[3] = S[4][0]; DrawPolygon(p); // for (int i = 0; i < n - 1; i++) { p[0] = S[5][i]; p[1] = S[6][i]; p[2] = S[6][i + 1]; p[3] = S[5][i + 1]; DrawPolygon(p); } p[0] = S[5][n - 1]; p[1] = S[6][n - 1]; p[2] = S[6][0]; p[3] = S[5][0]; DrawPolygon(p); // p[0] = S[7][0]; for (int i = 0; i < n - 1; i++) { p[1] = S[6][i]; p[2] = S[6][i + 1]; DrawPolygon(p); } p[1] = S[6][n - 1]; p[2] = S[6][0]; DrawPolygon(p); for (int i = 8; i < 12; i++) DrawPolygon(S[i]); } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth buffers //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); draw_axis(); glColor3f(0.3, 0.3, 0.3); drawBase(base0, 0); drawBase(base1, 1); drawSides(); nacrtajStralicu(S, 20); glutSwapBuffers(); // Swap the front and back frame buffers (double buffering) } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(WINDOW_HEIGHT * aspectRatio, WINDOW_HEIGHT); glutInitWindowPosition(50, 50); glutCreateWindow(title); base0 = createBase(r, R, l, n_zupcanika, 0); base1 = createBase(r, R, l, n_zupcanika, 1); Vector3D ktranslate(0.0, -k, 0.0); base1 = Matrix4x4::Translate(base1, ktranslate); base0 = Matrix4x4::Translate(base0, centar); base1 = Matrix4x4::Translate(base1, centar); Vector3D osaY(0.0, 1.0, 0.0); for (int i = 0; i < base0[2].size(); i++) { Vector3D osaRotacije = base0[2][i].Cross(osaY); Vector3D centarRotacije = base0[2][i]; centarRotacije.Normalize(); centarRotacije = centarRotacije * r; double konus = phi_konus; if (osaRotacije.Z() < 0.000001) { konus = -phi_konus; } Matrix4x4 matrix; matrix = Matrix4x4::CreateRotationMatrix(centarRotacije, osaRotacije, M_PI / 180.0 * konus); base0[2][i] = matrix.Transform(base0[2][i]); base1[3][i] = matrix.Transform(base1[3][i]); osaRotacije = base0[1][i].Cross(osaY); centarRotacije = base0[1][i]; konus = phi_konus; if (osaRotacije.Z() < 0.000001) { konus = -phi_konus; } matrix = Matrix4x4::CreateRotationMatrix(centarRotacije, osaRotacije, M_PI / 180.0 * konus); base1[2][i] = matrix.Transform(base1[2][i]); } Vector3D OsaRot = N.Cross(osaY); double phi = N.AngleBetween(osaY); Matrix4x4 matrixR; matrixR = Matrix4x4::CreateRotationMatrix(centar, OsaRot,- phi); base0 = matrixR.Transform(base0); base1 = matrixR.Transform(base1); kreirajStrelicu(S, 0.1, 0.25, 0.15, 1, 1.5, 0.5, 5, 4, M_PI * 0.4, M_PI * 0.4, 20); glutTimerFunc(1000 / FPS, timer, 1); glutDisplayFunc(display); SetCamera(); initGL(); glutMainLoop(); return 0; }