Previous Entry Next Entry→

August 24, 2005

Take a dash of trip to the beach, a hefty helping of jury duty and mix with intractable probability problem and you've got a recipe for time consumption.

 The code is now to where I it sorts the random triangle vertices in increasing order of x coordinates, computes the edge coordinates and makes a very rudimentary attempt to draw the "shadow polygons" where a fourth point would not form a convex quadrilateral.  There is a constant float called "GRID" which allows for this to happen repeatedly in one plot.  With GRID set to 4, I get, for instance, 16 plots in a picture like the one shown at right.  The picture is badly cropped (I need to learn a few things about saving these pics) The original random triangle is the red one.  If it works out right, each vertex of the red triangle touches a green triangle at a single point, forming congruent vertex angles at that point.  This ideal is most clearly realized in the lower right of the 16 examples shown in the graphic at right.

// Based on code from OpenGl Primer by Edward Angel
#include <GL/glut.h>
#include <math.h>
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
#define NULL 0

const float GRID = 4.0;

int doubleb; //window ids //singleb,

//prototypes
void display();
void keyIt(unsigned char, int, int);
void reshapeIt(int, int);
void display();
void drawObjects(GLenum);
void sortVertices(float [3][2]);
void printVertices(float [3][2]);
void edgePoints(float [3][2],float [6][2],float,float);

////////////////////////////////////////
int main(int argc, char** argv) {
glutInit(&argc, argv);
//create a double buffered window
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
doubleb = glutCreateWindow("double buffered");
//initIt();
glutDisplayFunc(display);
glutReshapeFunc(reshapeIt);
glutIdleFunc(display);
//glutMouseFunc(mouse);
//Enter event loop
glutMainLoop();
}

void display() {
glClear(GL_COLOR_BUFFER_BIT);
drawObjects(GL_RENDER);
glutSwapBuffers();
}

void drawObjects(GLenum mode) {
float t[3][2];
float edgePts[6][2];
char a;
// Draw a 10X10 grid of triangole pictures.
for(float i = 0; i < 1.0; i+=1./GRID) {
for(float j = 0; j < 1.0; j+=1./GRID) {
for(int k= 0;k<3;++k) {
t[k][0] = (float) rand()/(GRID*RAND_MAX)+i;
t[k][1] = (float) rand()/(GRID*RAND_MAX)+j;
}
sortVertices(t);
printVertices(t);
// Compute and report edgepoints for each triangle
edgePoints(t,edgePts,i,j);
glColor3f(1.0,0.0,0.0); //red
glBegin(GL_TRIANGLES);
glVertex2fv(t[0]);
glVertex2fv(t[1]);
glVertex2fv(t[2]);
glEnd();
glColor3f(0.0,1.0,0.0);
glBegin(GL_TRIANGLES);
glVertex2fv(t[0]);
glVertex2fv(edgePts[0]);
glVertex2fv(edgePts[4]);
glVertex2fv(t[1]);
glVertex2fv(edgePts[1]);
glVertex2fv(edgePts[2]);
glVertex2fv(t[2]);
glVertex2fv(edgePts[3]);
glVertex2fv(edgePts[5]);
glEnd();
cin.get(a);
}
}
}

void sortVertices(float t[3][2]) {
float temp;
if(t[1][0]<t[0][0]) {
temp = t[0][0];
t[0][0] = t[1][0];
t[1][0] = temp;
temp = t[0][1];
t[0][1] = t[1][1];
t[1][1] = temp;
}
if(t[2][0]<t[1][0]) {
temp = t[1][0];
t[1][0] = t[2][0];
t[2][0] = temp;
temp = t[1][1];
t[1][1] = t[2][1];
t[2][1] = temp;
}
if(t[1][0]<t[0][0]) {
temp = t[0][0];
t[0][0] = t[1][0];
t[1][0] = temp;
temp = t[0][1];
t[0][1] = t[1][1];
t[1][1] = temp;
}
}

void edgePoints(float t[3][2], float edgePts[6][2], float xIndex, float yIndex) {
float x,y;

// Sort the points in increasing order of x.
// Note: this should be tightened up with a bubble sort...

// compute where triangle lines intersect perimeter of unit square
// start by computing the three slopes:

float m[3];
m[0] = (t[0][1] - t[1][1])
/(t[0][0] - t[1][0]);
m[1] = (t[1][1] - t[2][1])
/(t[1][0] - t[2][0]);
m[2] = (t[2][1] - t[0][1])
/(t[2][0] - t[0][0]);
// for each vertex, compute the other two vertices of the
// polygon whose area we want, which are where the extended
// triangle edges meet the perimeter of the unit square.
// x0,y0
int next = 0;
//for each extended edge
for(int e = 0; e < 3; ++e) {
y = t[e][1] + m[e]*(xIndex-t[e][0]);
if(yIndex<y && y<yIndex+1./GRID) {
edgePts[next][0] = xIndex;
edgePts[next][1] = y;
++next;
}
y = t[e][1] + m[e]*(xIndex+1./GRID-t[e][0]);
if(yIndex<y && y<yIndex+1./GRID) {
edgePts[next][0] = xIndex+1./GRID;
edgePts[next][1] = y;
++next;
}
x = t[e][0] + (yIndex-t[e][1])/m[e];
if(xIndex<x && x<xIndex+1./GRID) {
edgePts[next][0] = x;
edgePts[next][1] = yIndex;
++next;
}
x = t[e][0] +(yIndex+1./GRID-t[e][1])/m[e];
if(xIndex<x && x<xIndex+1./GRID) {
edgePts[next][0] = x;
edgePts[next][1] = yIndex+1./GRID;
++next;
}
}
// print out
cout << "\nThe edge points are:\n";
for(int i = 0; i < 6; ++i)
cout << edgePts[i][0] << " " << edgePts[i][1] << endl;
//cin >> x;

}

void reshapeIt(int w, int h) {
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,1.0,0.0,1.0);
glMatrixMode(GL_MODELVIEW);
}
void printVertices(float t[3][2]) {
cout << "\nThe triangle has coordinates: \n";
for(int i = 0; i < 3; ++i)
cout << t[i][0] << " " << t[i][1] << endl;
}
// Both a keyboard and a mouse callback are illustrated here
/*void keyIt(unsigned char key, int x, int y) {
if(key == 'Q' || key == 'q') exit(0);
}