// This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Copyright 2007, Daniel Fontijne, University of Amsterdam -- fontijne@science.uva.nl // Edited by Arnoud Visser, Universiteit van Amsterdam -- A.Visser@uva.nl // // This is a partly port of the example chap2ex1.cpp to chap2ex1.cs // This port is not complete, 34 errors and 22 warnings remain. //#ifdef WIN32 //#include //#endif //#include //#include //#include //#include //#include //#include //#include //#include //#include //#include //#include using System; using Tao.OpenGl; using Tao.FreeGlut; namespace e2ga_ns { public class Chap2Ex1 : e2ga { //const char *WINDOW_TITLE = "Geometric Algebra, Chapter 2, Example 1: Drawing Bivectors"; // GLUT state information int g_viewportWidth = 800; int g_viewportHeight = 600; int g_GLUTmenu; bool g_drawParallelogram = true; void display() { // doIntelWarning(); // warn for possible problems with picking on Intel graphics chipsets Gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); Gl.glViewport(0, 0, g_viewportWidth, g_viewportHeight); Gl.glMatrixMode(Gl.GL_PROJECTION); Gl.glLoadIdentity(); Gl.glOrtho(0, g_viewportWidth, 0, g_viewportHeight, -100.0, 100.0); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glLoadIdentity(); Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glDisable(Gl.GL_CULL_FACE); Gl.glPolygonMode(Gl.GL_FRONT_AND_BACK, Gl.GL_FILL); Gl.glMatrixMode(Gl.GL_MODELVIEW); Gl.glPushMatrix(); // we store the label positions & text here: std::vector labelString; std::vector labelPos; // how many bivectors? what spacing between them?: const float entryWidth = 2.75f; const float entryHeight = 3.5f; const int nbBivectorX = 6; const int nbBivectorY = 4; // scale / translate to right transform: const float scale = 40.0f; Gl.glScalef(scale, scale, scale); Gl.glTranslatef(entryWidth, ((float)nbBivectorY - 0.5f) * entryHeight, 0.0f); int posX = 0; e2ga::vector v1, v2, v1_plus_v2; bivector B; double step = 2 * Math.PI / (nbBivectorX * nbBivectorY); for (double a = 0; a < 2 * Math.PI; a += step) { // vector 1 is fixed to e1 v1 = e1; // compute vector 2: v2 = cos(a) * e1 + sin(a) * e2; // compute the bivector: B = v1 ^ v2; // draw vector 1 (red), vector 2 (green) Gl.glColor3f(1.0f, 0.0f, 0.0f); e2ga.draw(v1); Gl.glColor3f(0.0f, 1.0f, 0.0f); e2ga.draw(v2); // draw outer product v1^v2: Gl.glColor3f(0.0f, 0.0f, 1.0f); if (!g_drawParallelogram) { e2ga.draw(B); } else { Gl.glDisable(Gl.GL_CULL_FACE); v1_plus_v2 = v1 + v2; // draw QUAD with vertices // origin -> v1 -> (v1+v2) -> v2 Gl.glBegin(Gl.GL_QUADS); Gl.glVertex2f(0.0f, 0.0f); Gl.glVertex2f(v1.e1(), v1.e2()); Gl.glVertex2f(v1_plus_v2.e1(), v1_plus_v2.e2()); Gl.glVertex2f(v2.e1(), v2.e2()); Gl.glEnd(); } // store label of bivector: { labelString.push_back(B.toString()); float[] pos = new float[2]; viewportCoordinates(e3ga._vector(0.35f * entryHeight * e3ga.e2).getC(e3ga.vector_e1_e2_e3), pos); labelPos.push_back(vector(vector_e1_e2, pos)); } // translate to next entry: Gl.glTranslatef(entryWidth, 0.0f, 0.0f); posX++; if (posX == nbBivectorX) { posX = 0; Gl.glTranslatef(-(float)nbBivectorX * entryWidth, -entryHeight, 0.0f); } } Gl.glPopMatrix(); // draw the labels: Gl.glColor3f(0.2f, 0.2f, 0.2f); void* font = Glut.GLUT_BITMAP_HELVETICA_12; for (uint i = 0; i < labelString.size(); i++) { float w = getBitmapStringWidth(font, labelString[i].c_str()); renderBitmapString(labelPos[i].e1() - 0.45f * w, labelPos[i].e2(), font, labelString[i].c_str()); } Glut.glutSwapBuffers(); } void reshape(int width, int height) { g_viewportWidth = width; g_viewportHeight = height; } void menuCallback(int value) { g_drawParallelogram = value != 0; // redraw viewport Glut.glutPostRedisplay(); } public static void Main(String[] args) { // profiling for Gaigen 2: //e2ga::g2Profiling::init(); //e3ga::g2Profiling::init(); // GLUT Window Initialization: Glut.glutInit(&argc, argv); Glut.glutInitWindowSize(g_viewportWidth, g_viewportHeight); Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_ALPHA | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH); Glut.glutCreateWindow(WINDOW_TITLE); // Register callbacks: Glut.glutDisplayFunc(Me.display); Glut.glutReshapeFunc(Me.reshape); g_GLUTmenu = Glut.glutCreateMenu(Me.menuCallback); Glut.glutAddMenuEntry("disc", 0); Glut.glutAddMenuEntry("parallelogram", 1); Glut.glutAttachMenu(Glut.GLUT_LEFT_BUTTON); Glut.glutAttachMenu(Glut.GLUT_MIDDLE_BUTTON); Glut.glutAttachMenu(Glut.GLUT_RIGHT_BUTTON); Glut.glutMainLoop(); //return 0; } } // end of class Chap2Ex1 } // end of namespace e2ga_ns