Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
23 views

Computer Graphics and Animation Assignment 1

The document outlines a series of programming tasks related to computer graphics using OpenGL and GLUT. It includes algorithms for positioning objects, scaling, rotating, interactive sketching, pattern recognition methods, and creating sliders for user input. Each task is accompanied by example code demonstrating the implementation of the described functionality.

Uploaded by

Paul Phineas
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

Computer Graphics and Animation Assignment 1

The document outlines a series of programming tasks related to computer graphics using OpenGL and GLUT. It includes algorithms for positioning objects, scaling, rotating, interactive sketching, pattern recognition methods, and creating sliders for user input. Each task is accompanied by example code demonstrating the implementation of the described functionality.

Uploaded by

Paul Phineas
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 44

COURSE: T.I.

E
UNIT: COMPUTER GRAPHICS
NAME: JUSTUS CHEGE
REGISTRATION NUMBER: E020-01-
0854/2020.
TASK : ASSIGNMENT
1. Design an algorithm that allows objects to be positioned on the screen using a locator
device. An object menu of geometric shapes is to be presented to a user who is to select
an object and a placement position. The program should allow any number of objects to
be positioned until a “terminate” signal is given.
#include <GL/glut.h>
#include <stdio.h>

#define MAX_OBJECTS 100

typedef struct {
float x, y;
int shape;
} Object;

Object objects[MAX_OBJECTS];
int numObjects = 0;

void display() {
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 0; i < numObjects; i++) {
glPushMatrix();
glTranslatef(objects[i].x, objects[i].y, 0.0);
if (objects[i].shape == 1) {
glutSolidSphere(0.05, 20, 20);
} else if (objects[i].shape == 2) {
glutSolidCube(0.1);
}
glPopMatrix();
}
glutSwapBuffers();
}
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && numObjects <
MAX_OBJECTS) {
objects[numObjects].x = (float)x / 250 - 1;
objects[numObjects].y = 1 - (float)y / 250;
objects[numObjects].shape = 1; // default shape is sphere
numObjects++;
glutPostRedisplay();
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("Object Positioning");
glClearColor(1.0, 1.0, 1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

2. Extend the algorithm of the previous exercise so that selected objects can be scaled
and rotated before positioning. The transformation choices and transformation
parameters are to be presented to the user as menu options.
#include <GL/glut.h>
#include <stdio.h>

#define MAX_OBJECTS 100


typedef struct {
float x, y;
int shape;
float scale;
float rotation;
} Object;

Object objects[MAX_OBJECTS];
int numObjects = 0;

void display() {
glClear(GL_COLOR_BUFFER_BIT);
for (int i = 0; i < numObjects; i++) {
glPushMatrix();
glTranslatef(objects[i].x, objects[i].y, 0.0);
glScalef(objects[i].scale, objects[i].scale, 1.0);
glRotatef(objects[i].rotation, 0.0, 0.0, 1.0);
if (objects[i].shape == 1) {
glutSolidSphere(0.05, 20, 20);
} else if (objects[i].shape == 2) {
glutSolidCube(0.1);
}
glPopMatrix();
}
glutSwapBuffers();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && numObjects <
MAX_OBJECTS) {
objects[numObjects].x = (float)x / 250 - 1;
objects[numObjects].y = 1 - (float)y / 250;
objects[numObjects].shape = 1; // default shape is sphere
objects[numObjects].scale = 1.0; // default scale
objects[numObjects].rotation = 0.0; // default rotation
numObjects++;
glutPostRedisplay();
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("Object Positioning with Transformations");
glClearColor(1.0, 1.0, 1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

3. Set up a procedure for interactively sketching pictures using a stroke device.


#include <GL/glut.h>
#include <vector>

std::vector<std::pair<float, float>> points;

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_STRIP);
for (auto& point : points) {
glVertex2f(point.first, point.second);
}
glEnd();
glutSwapBuffers();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
float fx = (float)x / 250 - 1;
float fy = 1 - (float)y / 250;
points.push_back({fx, fy});
glutPostRedisplay();
}
}

void motion(int x, int y) {


float fx = (float)x / 250 - 1;
float fy = 1 - (float)y / 250;
points.push_back({fx, fy});
glutPostRedisplay();
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("Interactive Sketching");
glClearColor(1.0, 1.0, 1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}

4. Discuss the methods that could be employed in a pattern-recognition procedure to


match input characters against a stored library of shapes.
i. Template Matching: Compare the input pattern against stored templates and find the best
match.
ii. Feature Extraction: Extract features (like edges, corners) and use machine learning
algorithms to recognize patterns.
iii. Neural Networks: Train neural networks on labeled data to recognize shapes.
iv. Statistical Methods: Use statistical methods to analyze patterns and classify them based
on predefined criteria.

5. Write a routine that displays a linear scale and a slider on the screen and allows
numeric values to be selected by positioning the slide along the scale line. The selected
numeric value is to be echoed in a box displayed near the linear scale.
#include <GL/glut.h>
#include <stdio.h>

float sliderPos = 0.5;

void display() {
glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_LINES);
glVertex2f(-0.8, -0.5);
glVertex2f(0.8, -0.5);
glEnd();
glPushMatrix();
glTranslatef(sliderPos, -0.5, 0.0);
glutSolidCube(0.05);
glPopMatrix();

char buffer[10];
sprintf(buffer, "%.2f", sliderPos);
glRasterPos2f(-0.95, 0.8);
for (char* c = buffer; *c != '\0'; c++) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c);
}

glutSwapBuffers();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
sliderPos = (float)x / 250 - 1;
if (sliderPos < -0.8) sliderPos = -0.8;
if (sliderPos > 0.8) sliderPos = 0.8;
glutPostRedisplay();
}
}

void motion(int x, int y) {


sliderPos = (float)x / 250 - 1;
if (sliderPos < -0.8) sliderPos = -0.8;
if (sliderPos > 0.8) sliderPos = 0.8;
glutPostRedisplay();
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow("Linear Slider");
glClearColor(1.0, 1.0, 1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}

6. Write a program that makes use of the slider developed in the previous exercise to
allow the user to scale an object displayed in a display window between some minimum
and maximum value.
// Exercise 6 code - Scaling object using linear slider
#include <GL/glut.h>

float sliderPosition = 0.0;


float scaleFactor = 1.0;

void display() {
glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();
glScalef(scaleFactor, scaleFactor, 1);
glBegin(GL_QUADS);
glVertex2f(-0.5, -0.5);
glVertex2f(0.5, -0.5);
glVertex2f(0.5, 0.5);
glVertex2f(-0.5, 0.5);
glEnd();
glPopMatrix();

glBegin(GL_LINES);
glVertex2f(-1, -0.8);
glVertex2f(1, -0.8);
glEnd();

glPushMatrix();
glTranslatef(sliderPosition, -0.8, 0);
glBegin(GL_QUADS);
glVertex2f(-0.05, -0.1);
glVertex2f(0.05, -0.1);
glVertex2f(0.05, 0.1);
glVertex2f(-0.05, 0.1);
glEnd();
glPopMatrix();

char buffer[10];
sprintf(buffer, "%0.2f", scaleFactor);
glRasterPos2f(sliderPosition, -0.5);
for (char* c = buffer; *c != '\0'; c++) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c);
}

glFlush();
}
void mouse(int button, int state, int x, int y) {
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
sliderPosition = (float)x / 250 - 1;
scaleFactor = (sliderPosition + 1) * 0.5 + 0.5;
glutPostRedisplay();
}
}

void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Scaling Object with Slider");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
7. Write a routine that displays a circular scale and a pointer or a slider that can be
moved around the circle to select angles (in degrees). The angular value selected is to be
echoed in a box displayed near the circular scale.
// Exercise 7 code - Circular scale with a pointer
#include <GL/glut.h>
#include <math.h>

float angle = 0.0;

void display() {
glClear(GL_COLOR_BUFFER_BIT);

glBegin(GL_LINE_LOOP);
for (int i = 0; i < 360; i++) {
float theta = i * 3.14159 / 180;
glVertex2f(cos(theta), sin(theta));
}
glEnd();

glPushMatrix();
glRotatef(angle, 0, 0, 1);
glBegin(GL_LINES);
glVertex2f(0, 0);
glVertex2f(1, 0);
glEnd();
glPopMatrix();

char buffer[10];
sprintf(buffer, "%0.2f", angle);
glRasterPos2f(1.2, 0);
for (char* c = buffer; *c != '\0'; c++) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c);
}

glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
float dx = x - 250;
float dy = 250 - y;
angle = atan2(dy, dx) * 180 / 3.14159;
if (angle < 0) angle += 360;
glutPostRedisplay();
}
}

void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.5, 1.5, -1.5, 1.5);
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Circular Scale with Pointer");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

8. Write a program that makes use of the circular slider developed in the previous
exercise to allow the user to rotate an object around its center.
// Exercise 8 code - Rotating object using circular slider
#include <GL/glut.h>
#include <math.h>

float angle = 0.0;

void display() {
glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();
glRotatef(angle, 0, 0, 1);
glBegin(GL_QUADS);
glVertex2f(-0.5, -0.5);
glVertex2f(0.5, -0.5);
glVertex2f(0.5, 0.5);
glVertex2f(-0.5, 0.5);
glEnd();
glPopMatrix();

glBegin(GL_LINE_LOOP);
for (int i = 0; i < 360; i++) {
float theta = i * 3.14159 / 180;
glVertex2f(cos(theta), sin(theta));
}
glEnd();

glPushMatrix();
glRotatef(angle, 0, 0, 1);
glBegin(GL_LINES);
glVertex2f(0, 0);
glVertex2f(1, 0);
glEnd();
glPopMatrix();

char buffer[10];
sprintf(buffer, "%0.2f", angle);
glRasterPos2f(1.2, 0);
for (char* c = buffer; *c != '\0'; c++) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c);
}

glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
float dx = x - 250;
float dy = 250 - y;
angle = atan2(dy, dx) * 180 / 3.14159;
if (angle < 0) angle += 360;
glutPostRedisplay();
}
}

void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.5, 1.5, -1.5, 1.5);
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("Rotating Object with Circular Slider");
init();
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

9. Write a drawing program that allows users to create a picture as a set of straight-line
segments drawn between specified endpoints. The coordinates of the individual line
segments are to be selected with a locator device.
#include <GL/glut.h>
#include <vector>

struct Point {
float x, y;
};

std::vector<Point> points;

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
for (size_t i = 0; i < points.size(); i += 2) {
glVertex2f(points[i].x, points[i].y);
glVertex2f(points[i + 1].x, points[i + 1].y);
}
glEnd();
glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
Point p = { (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0,
1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0) };
points.push_back(p);
if (points.size() % 2 == 0) {
glutPostRedisplay();
}
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Drawing Program");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

10. Write a drawing package that allows pictures to be created with straight-line
segments drawn between specified endpoints. Set up a gravity field around each line in
a picture, as an aid in connecting new lines to existing lines.
#include <GL/glut.h>
#include <vector>
#include <cmath>

struct Point {
float x, y;
};

std::vector<Point> points;
const float GRAVITY_RADIUS = 0.05f;
bool constrainToHV = false;

bool nearExistingPoint(float x, float y, Point& nearPoint) {


for (const auto& p : points) {
if (std::sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y)) < GRAVITY_RADIUS) {
nearPoint = p;
return true;
}
}
return false;
}

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
for (size_t i = 0; i < points.size(); i += 2) {
glVertex2f(points[i].x, points[i].y);
glVertex2f(points[i + 1].x, points[i + 1].y);
}
glEnd();
glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
Point p = { fx, fy };

Point nearPoint;
if (nearExistingPoint(fx, fy, nearPoint)) {
p = nearPoint;
}

if (points.size() % 2 == 1 && constrainToHV) {


Point lastPoint = points.back();
if (std::abs(fx - lastPoint.x) < std::abs(fy - lastPoint.y)) {
p.x = lastPoint.x;
} else {
p.y = lastPoint.y;
}
}

points.push_back(p);
if (points.size() % 2 == 0) {
glutPostRedisplay();
}
}
}

void keyboard(unsigned char key, int x, int y) {


if (key == 'h' || key == 'v') {
constrainToHV = !constrainToHV;
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Drawing Program with Constraints");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}

11. Modify the drawing package in the previous exercise so that lines can be constrained
horizontally or vertically.
#include <GL/glut.h>
#include <vector>
#include <cmath>

struct Point {
float x, y;
};

std::vector<Point> points;
const float GRAVITY_RADIUS = 0.05f;
bool constrainToHV = false;

bool nearExistingPoint(float x, float y, Point& nearPoint) {


for (const auto& p : points) {
if (std::sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y)) < GRAVITY_RADIUS) {
nearPoint = p;
return true;
}
}
return false;
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
for (size_t i = 0; i < points.size(); i += 2) {
glVertex2f(points[i].x, points[i].y);
glVertex2f(points[i + 1].x, points[i + 1].y);
}
glEnd();
glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
Point p = { fx, fy };

Point nearPoint;
if (nearExistingPoint(fx, fy, nearPoint)) {
p = nearPoint;
}

if (points.size() % 2 == 1 && constrainToHV) {


Point lastPoint = points.back();
if (std::abs(fx - lastPoint.x) < std::abs(fy - lastPoint.y)) {
p.x = lastPoint.x;
} else {
p.y = lastPoint.y;
}
}
points.push_back(p);
if (points.size() % 2 == 0) {
glutPostRedisplay();
}
}
}

void keyboard(unsigned char key, int x, int y) {


if (key == 'h' || key == 'v') {
constrainToHV = !constrainToHV;
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Drawing Program with Constraints");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
12. Develop a drawing package that can display an optional grid pattern so that selected
screen positions are rounded to grid intersections. The package is to provide line-
drawing capabilities, with line endpoints selected using a locator device.
#include <GL/glut.h>
#include <vector>
#include <cmath>

struct Point {
float x, y;
};

std::vector<Point> points;
const float GRID_SIZE = 0.1f;
bool showGrid = true;

void drawGrid() {
glColor3f(0.9, 0.9, 0.9);
glBegin(GL_LINES);
for (float i = -1; i <= 1; i += GRID_SIZE) {
glVertex2f(i, -1);
glVertex2f(i, 1);
glVertex2f(-1, i);
glVertex2f(1, i);
}
glEnd();
}

void display() {
glClear(GL_COLOR_BUFFER_BIT);
if (showGrid) {
drawGrid();
}
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_LINES);
for (size_t i = 0; i < points.size(); i += 2) {
glVertex2f(points[i].x, points[i].y);
glVertex2f(points[i + 1].x, points[i + 1].y);
}
glEnd();
glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);

fx = roundf(fx / GRID_SIZE) * GRID_SIZE;


fy = roundf(fy / GRID_SIZE) * GRID_SIZE;

Point p = { fx, fy };
points.push_back(p);
if (points.size() % 2 == 0) {
glutPostRedisplay();
}
}
}

void keyboard(unsigned char key, int x, int y) {


if (key == 'g') {
showGrid = !showGrid;
glutPostRedisplay();
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Drawing Program with Grid");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}

13. Write a routine that allows a designer to create a picture by sketching straight lines
using a rubber-band method.
#include <GL/glut.h>
#include <vector>

struct Point {
float x, y;
};
std::vector<Point> points;
Point currentPoint;
bool drawing = false;

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
for (size_t i = 0; i < points.size(); i += 2) {
glVertex2f(points[i].x, points[i].y);
glVertex2f(points[i + 1].x, points[i + 1].y);
}
if (drawing) {
glVertex2f(points.back().x, points.back().y);
glVertex2f(currentPoint.x, currentPoint.y);
}
glEnd();
glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
Point p = { (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0,
1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0) };
points.push_back(p);
drawing = !drawing;
if (!drawing) {
glutPostRedisplay();
}
}
}
void motion(int x, int y) {
if (drawing) {
currentPoint = { (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0,
1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0) };
glutPostRedisplay();
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Drawing Program with Rubber Band");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}

14. Design a drawing package that allows straight lines, rectangles, and circles to be
constructed using rubber-band methods.
#include <GL/glut.h>
#include <vector>
#include <cmath>
struct Point {
float x, y;
};

std::vector<Point> points;
Point currentPoint;
bool drawing = false;
enum DrawMode { LINE, RECTANGLE, CIRCLE } drawMode = LINE;

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
for (size_t i = 0; i < points.size(); i += 2) {
glVertex2f(points[i].x, points[i].y);
glVertex2f(points[i + 1].x, points[i + 1].y);
}
glEnd();
if (drawing) {
switch (drawMode) {
case LINE:
glBegin(GL_LINES);
glVertex2f(points.back().x, points.back().y);
glVertex2f(currentPoint.x, currentPoint.y);
glEnd();
break;
case RECTANGLE:
glBegin(GL_LINE_LOOP);
glVertex2f(points.back().x, points.back().y);
glVertex2f(currentPoint.x, points.back().y);
glVertex2f(currentPoint.x, currentPoint.y);
glVertex2f(points.back().x, currentPoint.y);
glEnd();
break;
case CIRCLE:
glBegin(GL_LINE_LOOP);
float radius = std::sqrt(std::pow(currentPoint.x - points.back().x, 2) +
std::pow(currentPoint.y - points.back().y, 2));
for (int i = 0; i <= 300; i++) {
float angle = 2 * 3.14159265358979323846 * i / 300;
float dx = radius * cosf(angle);
float dy = radius * sinf(angle);
glVertex2f(points.back().x + dx, points.back().y + dy);
}
glEnd();
break;
}
}
glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
Point p = { (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0,
1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0) };
points.push_back(p);
drawing = !drawing;
if (!drawing) {
glutPostRedisplay();
}
}
}

void motion(int x, int y) {


if (drawing) {
currentPoint = { (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0,
1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0) };
glutPostRedisplay();
}
}

void keyboard(unsigned char key, int x, int y) {


if (key == 'l') {
drawMode = LINE;
} else if (key == 'r') {
drawMode = RECTANGLE;
} else if (key == 'c') {
drawMode = CIRCLE;
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Drawing Program with Rubber Band and Shapes");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}

15. Write a procedure that allows a user to pick components of a two-dimensional scene.
The coordinate extents for each object are to be stored and used to identify the picked
object, given an input cursor position.
#include <GL/glut.h>
#include <vector>
#include <iostream>

struct Point {
float x, y;
};

struct BoundingBox {
Point min;
Point max;
};

std::vector<Point> points;
std::vector<BoundingBox> boundingBoxes;
bool drawing = false;

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINES);
for (size_t i = 0; i < points.size(); i += 2) {
glVertex2f(points[i].x, points[i].y);
glVertex2f(points[i + 1].x, points[i + 1].y);
}
glEnd();
glFlush();
}

bool pointInBox(const Point& p, const BoundingBox& box) {


return p.x >= box.min.x && p.x <= box.max.x && p.y >= box.min.y && p.y <=
box.max.y;
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
Point p = { (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0,
1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0) };
points.push_back(p);
drawing = !drawing;
if (!drawing) {
BoundingBox box;
box.min = { std::min(points.back().x, p.x), std::min(points.back().y, p.y) };
box.max = { std::max(points.back().x, p.x), std::max(points.back().y, p.y) };
boundingBoxes.push_back(box);
glutPostRedisplay();
}
} else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
Point p = { (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0,
1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0) };
for (size_t i = 0; i < boundingBoxes.size(); ++i) {
if (pointInBox(p, boundingBoxes[i])) {
std::cout << "Picked object " << i << std::endl;
break;
}
}
}
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Picking in 2D Scene");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}

16. Develop a procedure that allows a user to design a picture from a menu of displayed
basic shapes by dragging each selected shape into position with a pick device.
#include <GL/glut.h>
#include <vector>
#include <iostream>

struct Shape {
enum Type { CIRCLE, RECTANGLE } type;
float x, y;
bool selected;
};

std::vector<Shape> shapes;
Shape *selectedShape = nullptr;
int menu;
bool dragging = false;

void drawCircle(float x, float y, float radius) {


glBegin(GL_LINE_LOOP);
for (int i = 0; i <= 300; i++) {
float angle = 2 * 3.14159265358979323846 * i / 300;
float dx = radius * cosf(angle);
float dy = radius * sinf(angle);
glVertex2f(x + dx, y + dy);
}
glEnd();
}

void drawRectangle(float x, float y, float width, float height) {


glBegin(GL_LINE_LOOP);
glVertex2f(x, y);
glVertex2f(x + width, y);
glVertex2f(x + width, y + height);
glVertex2f(x, y + height);
glEnd();
}

void display() {
glClear(GL_COLOR_BUFFER_BIT);

for (const auto& shape : shapes) {


if (shape.type == Shape::CIRCLE) {
drawCircle(shape.x, shape.y, 0.1);
} else if (shape.type == Shape::RECTANGLE) {
drawRectangle(shape.x, shape.y, 0.2, 0.1);
}
}
glFlush();
}

void mouse(int button, int state, int x, int y) {


float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {


for (auto& shape : shapes) {
if ((shape.type == Shape::CIRCLE &&
sqrt(pow(fx - shape.x, 2) + pow(fy - shape.y, 2)) < 0.1) ||
(shape.type == Shape::RECTANGLE &&
fx >= shape.x && fx <= shape.x + 0.2 &&
fy >= shape.y && fy <= shape.y + 0.1)) {
shape.selected = true;
selectedShape = &shape;
dragging = true;
break;
}
}
} else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
if (dragging) {
dragging = false;
selectedShape = nullptr;
}
}
}

void motion(int x, int y) {


if (dragging && selectedShape) {
selectedShape->x = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
selectedShape->y = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
glutPostRedisplay();
}
}

void menuHandler(int option) {


Shape newShape;
newShape.x = -0.9;
newShape.y = 0.9;
newShape.selected = false;

if (option == 1) {
newShape.type = Shape::CIRCLE;
} else if (option == 2) {
newShape.type = Shape::RECTANGLE;
}
shapes.push_back(newShape);
glutPostRedisplay();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Drag and Drop Shapes");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);

menu = glutCreateMenu(menuHandler);
glutAddMenuEntry("Circle", 1);
glutAddMenuEntry("Rectangle", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);

glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}

17. Design an implementation of the input functions for request mode.


#include <GL/glut.h>
#include <iostream>

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
std::cout << "Mouse clicked at: (" << fx << ", " << fy << ")" << std::endl;
}
}

void keyboard(unsigned char key, int x, int y) {


std::cout << "Key pressed: " << key << std::endl;
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Request Mode Input");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);

glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}

18. Design an implementation of the sample mode input functions.


#include <GL/glut.h>
#include <iostream>

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}

void mouseMotion(int x, int y) {


float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
std::cout << "Mouse moved to: (" << fx << ", " << fy << ")" << std::endl;
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Sample Mode Input");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);

glutDisplayFunc(display);
glutPassiveMotionFunc(mouseMotion);
glutMainLoop();
return 0;
}

19. Design an implementation of the input functions for event mode.


#include <GL/glut.h>
#include <iostream>

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}

void mouse(int button, int state, int x, int y) {


if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
std::cout << "Mouse clicked at: (" << fx << ", " << fy << ")" << std::endl;
}
}

void keyboard(unsigned char key, int x, int y) {


std::cout << "Key pressed: " << key << std::endl;
}

void motion(int x, int y) {


float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
std::cout << "Mouse dragged to: (" << fx << ", " << fy << ")" << std::endl;
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Event Mode Input");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);

glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutMainLoop();
return 0;
}

20. Design a procedure for implementing input functions for request, sample, and event
mode.
#include <GL/glut.h>
#include <iostream>

void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}

void mouse(int button, int state, int x, int y) {


float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);

if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {


std::cout << "Mouse clicked at: (" << fx << ", " << fy << ") - Request Mode" <<
std::endl;
}
}

void keyboard(unsigned char key, int x, int y) {


std::cout << "Key pressed: " << key << " - Event Mode" << std::endl;
}

void motion(int x, int y) {


float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
std::cout << "Mouse dragged to: (" << fx << ", " << fy << ") - Event Mode" << std::endl;
}

void passiveMotion(int x, int y) {


float fx = (float)x / (glutGet(GLUT_WINDOW_WIDTH) / 2.0) - 1.0;
float fy = 1.0 - (float)y / (glutGet(GLUT_WINDOW_HEIGHT) / 2.0);
std::cout << "Mouse moved to: (" << fx << ", " << fy << ") - Sample Mode" << std::endl;
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutCreateWindow("Request, Sample, and Event Mode Input");
glClearColor(1.0, 1.0, 1.0, 1.0);
glColor3f(0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, -1.0, 1.0);

glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutPassiveMotionFunc(passiveMotion);
glutMainLoop();
return 0;
}

You might also like