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 quit_menu(int);
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);
glLoadIdentity();
gluOrtho2D(0.0,1.0,0.0,1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
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);
}
void quit_menu(int id) {
if(id == 1) exit(0);
}*/
|