//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <gl.h> // The GL Header File
#include <glut.h> // The GL Utility Toolkit (Glut) Header
float hh = 0.1;
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//---------------------------------------- vector_sum ------------------------------------------
void vector_sum (float a[3], float b[3], float c[3])
{
c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
c[2] = a[2] + b[2];
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//---------------------------------------- vector_dif ------------------------------------------
void vector_dif (float a[3], float b[3], float c[3])
{
c[0] = a[0] - b[0];
c[1] = a[1] - b[1];
c[2] = a[2] - b[2];
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//----------------------------------------- vec_mag --------------------------------------------
// Return the magnitude of a 3D vector.
float vec_mag (float v[3])
{
return ((float)sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]));
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//--------------------------------------- vector_angle -----------------------------------------
// Return the angle between two vectors in radians.
float vector_angle (float a[3], float b[3])
{
float num, den;
num = a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
den = vec_mag(a) * vec_mag(b);
return ((float)acos(num/den));
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//--------------------------------------- unit_vector ------------------------------------------
void unit_vector (float v[3])
{
float mag;
mag = (float)sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] = v[0] / mag;
v[1] = v[1] / mag;
v[2] = v[2] / mag;
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//---------------------------------------- vec_scale -------------------------------------------
// Vector scale function.
void vec_scale (float vec[3], float s)
{
vec[0] *= s;
vec[1] *= s;
vec[2] *= s;
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//---------------------------------------- vec_cross -------------------------------------------
// Cross product of two 3D vectors
void vec_cross (float a[3], float b[3], float c[3])
{
c[0] = a[1] * b[2] - a[2] * b[1];
c[1] = a[2] * b[0] - a[0] * b[2];
c[2] = a[0] * b[1] - a[1] * b[0];
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//----------------------------------------- Keyboard -------------------------------------------
void Keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 'x': hh += 0.05; break;
case 'z': hh -= 0.05; break;
case 27: exit (0); break; // Quit program with 'esc' key.
default : printf (" Keyboard -> key = %d, key = %c\n", key, key); break;
}
glutPostRedisplay ();
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//------------------------------------------ Display -------------------------------------------
void Display (void)
{
int v, i, j;
float a[3], b[3], c[3], goly[5][3], x, alfa;
static short first = 1, convex[5];
static float poly[5][3] = {{-1.0,-2.0},{1.0,-2.0},{0.0,0.5},{0.0,3.0},{-3.0,0.4}};
// Convex = 1 -> convex vertex, convex = 0 -> concave vertex.
if (first) {
first = 0;
for (v = 0; v < 6; v++) {
i = (v - 1) % 5;
j = (v + 1) % 5;
vector_dif (poly[v], poly[i], a);
vector_dif (poly[j], poly[v], b);
vec_cross (a, b, c);
if (c[2] > 0.0) convex[v] = 1;
else convex[v] = 0;
}
}
glLoadIdentity ();
glClear (GL_COLOR_BUFFER_BIT);
// Extrude lines to get quads of thickness 'hh'.
// 'hh' can be interactively changed via the 'x' and 'z' keys.
for (v = 0; v < 5; v++) {
i = (v + 4) % 5;
j = (v + 1) % 5;
vector_dif (poly[i], poly[v], a);
vector_dif (poly[j], poly[v], b);
unit_vector (a);
unit_vector (b);
vector_sum (a, b, c);
unit_vector (c);
alfa = 0.5 * vector_angle (a,b);
x = hh / sin (alfa);
vec_scale (c, x);
if (convex[v]) vector_sum (poly[v], c, goly[v]);
else vector_dif (poly[v], c, goly[v]);
}
glBegin (GL_QUADS);
for (v = 0; v < 5; v++) {
j = (v + 1) % 5;
glColor3f (0.2, 0.1, 0.2);
glVertex3fv (poly[v]); glVertex3fv (poly[j]);
glColor3f (0.4, 0.9, 0.4);
glVertex3fv (goly[j]); glVertex3fv (goly[v]);
}
glEnd ();
glutSwapBuffers ();
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//------------------------------------------ Init_GL -------------------------------------------
void Init_GL (void)
{
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (-5.0,5.0, -5.0,5.0, -5.0,5.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glClearColor (0.2, 0.1, 0.2, 1.0);
}
//---+----4----+----3----+----2----+----1----+---/\---+----1----+----2----+----3----+----4----+---\\
//------------------------------------------- main ---------------------------------------------
void main (int argc, char** argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize (800, 800);
glutInitWindowPosition (350, 100);
glutCreateWindow ("Pillow Fill - Carmine");
glutKeyboardFunc (Keyboard);
glutDisplayFunc ( Display);
Init_GL();
glutMainLoop ();
}