Reputation: 79
My assignment is to perform transformations (reflections) on a 2D object.
Lets say my original object is a circle: o
I want to reflect it across a line y = 5 for example. o | o
Then I want to reflect the two objects across a line x = 5 for example.
o o
__
o o
Then finally I want to reflect the four objects across a line y = 10 for example.
o o | o o
o o | o o
So ultimately I want the end result to include 8 circles.
My question is, how would I go about implementing that into my code?
This is the code for my project:
#include <glut.h>
GLfloat square[4][3] = {{5, 0,0}, {5,20,0},{-5,20,0}, {-5,0,0}};
GLfloat square2[4][3] = { { 10, -5,0 },{ 10,25,0 },{ 0,25,0 },{ 0,-5,0 } };
GLfloat square3[4][3] = { { 0, -5,0 },{ 0,25,0 },{ -10,25,0 },{ -10,-5,0 } };
GLfloat colors[3][3] = {{0,0,1},{1,1,1},{0,0,0}};
void draw_square(void){
glBegin(GL_POLYGON);
for(int i = 0; i < 4; i++){
glVertex3fv(square[i]);
}
glEnd();
}
void draw_square2(void) {
glBegin(GL_POLYGON);
for (int i = 0; i < 4; i++) {
glVertex3fv(square2[i]);
}
glEnd();
}
void draw_square3(void) {
glBegin(GL_POLYGON);
for (int i = 0; i < 4; i++) {
glVertex3fv(square3[i]);
}
glEnd();
}
void draw_ring(void){
for(int r =0; r < 360;r+=45){
glPushMatrix();
glRotated(r, 0,0,1);
glTranslated(0,50,0);
draw_square();
glPopMatrix();
}
}
void draw_ring2(void) {
for (int r = 0; r < 360; r += 45) {
glPushMatrix();
glRotated(r, 0, 0, 1);
glTranslated(0, 50, 0);
draw_square2();
glPopMatrix();
}
}
void draw_ring3(void) {
for (int r = 0; r < 360; r += 45) {
glPushMatrix();
glRotated(r, 0, 0, 1);
glTranslated(0, 50, 0);
draw_square3();
glPopMatrix();
}
}
The display function below creates the set of overlapping rings that I want to reflect. The way it is now, I only get one set of overlapping rings at the bottom left corner. I want the output to be 8 sets of overlapping rings. Ive been trying to find a way to create the reflections I need, but i cant seem to figure it out.
void display(void){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3fv(colors[0]);
draw_ring();
glColor3fv(colors[1]);
draw_ring2();
glColor3fv(colors[2]);
draw_ring3();
glPopMatrix();
glFlush();
}
void main(int argc, char** argv){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(1000,600);
glutInitWindowPosition(200,100);
glutCreateWindow("Project 2");
glClearColor(1.0,1.0,0.0,1.0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-100.0, 1000.0, -100.0,600.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutDisplayFunc(display);
glutMainLoop();
}
Any help would be greatly appreciated.
Upvotes: 1
Views: 870
Reputation: 210877
Note, that drawing by glBegin
/glEnd
sequences and the fixed function pipeline matrix stack is deprecated since decades.
Read about Fixed Function Pipeline and see Vertex Specification and Shader for a state of the art way of rendering.
Anyway, if you want to tile the objects, then you can do this by nested loops:
void draw_object( void )
{
glPushMatrix();
glColor3fv(colors[0]);
draw_ring();
glColor3fv(colors[1]);
draw_ring2();
glColor3fv(colors[2]);
draw_ring3();
glPopMatrix();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
int tile_x = 4;
int tile_y = 2;
float tile_dist = 200.0f;
for ( int x = 0; x < tile_x; ++ x )
{
for (int y = 0; y < tile_y; ++ y )
{
glPushMatrix();
glTranslatef( (float)x * tile_dist, (float)y * tile_dist, 0.0f );
draw_object();
glPopMatrix();
}
}
glFlush();
}
The same tile effect can be achieved by a recursive function:
void display_tiles_recursive( int level, float dist )
{
if ( level == 0 )
{
draw_object();
return;
}
int tile = level / 2;
bool tile_x = level % 2 != 0;
float offset_x = tile_x ? pow(2.0f, (float)tile) * dist : 0.0f;
float offset_y = tile_x ? 0.0f : pow(2.0f, (float)(tile-1)) * dist;
glPushMatrix();
display_tiles_recursive( level - 1, dist );
glTranslatef( offset_x, offset_y, 0.0f );
display_tiles_recursive( level - 1, dist );
glPopMatrix();
}
void display_mirror(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
display_tiles_recursive( 3, 200.0f );
glFlush();
}
If you want to achieve a repeated mirror effect, then have to mirror the even tiles along the x and y axis. The mirroring can be achieved by glScale
. glScalef( -1.0f, 1.0f, 1.0f );
to mirror along the x-axis and glScalef( 1.0f, -1.0f, 1.0f );
to mirror along the y axis. You can extend the recursive tiling function to get this effect:
void display_mirror_recursive( int level, float dist, bool even_x, bool even_y )
{
if ( level == 0 )
{
glPushMatrix();
if ( even_x )
glScalef( -1.0f, 1.0f, 1.0f );
if ( even_y )
glScalef( 1.0f, -1.0f, 1.0f );
draw_object();
glPopMatrix();
return;
}
int tile = level / 2;
bool tile_x = level % 2 != 0;
float offset_x = tile_x ? pow(2.0f, (float)tile) * dist : 0.0f;
float offset_y = tile_x ? 0.0f : pow(2.0f, (float)(tile-1)) * dist;
glPushMatrix();
display_mirror_recursive( level - 1, dist, even_x, even_y );
glTranslatef( offset_x, offset_y, 0.0f );
if ( level == 1 )
even_y = !even_y;
if ( level == 2)
even_x = !even_x;
display_mirror_recursive( level - 1, dist, even_x, even_y );
glPopMatrix();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
display_mirror_recursive( 3, 200.0f, false, false );
glFlush();
}
Upvotes: 1