Computer Graphics and Animation Assignment 1
Computer Graphics and Animation Assignment 1
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>
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();
}
}
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>
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 display() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_LINE_STRIP);
for (auto& point : points) {
glVertex2f(point.first, point.second);
}
glEnd();
glutSwapBuffers();
}
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>
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();
}
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>
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);
}
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 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);
}
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>
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 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);
}
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();
}
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;
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();
}
Point nearPoint;
if (nearExistingPoint(fx, fy, nearPoint)) {
p = nearPoint;
}
points.push_back(p);
if (points.size() % 2 == 0) {
glutPostRedisplay();
}
}
}
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;
Point nearPoint;
if (nearExistingPoint(fx, fy, nearPoint)) {
p = nearPoint;
}
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();
}
Point p = { fx, fy };
points.push_back(p);
if (points.size() % 2 == 0) {
glutPostRedisplay();
}
}
}
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();
}
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();
}
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();
}
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 display() {
glClear(GL_COLOR_BUFFER_BIT);
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;
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
glutDisplayFunc(display);
glutPassiveMotionFunc(mouseMotion);
glutMainLoop();
return 0;
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
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();
}
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glutMotionFunc(motion);
glutPassiveMotionFunc(passiveMotion);
glutMainLoop();
return 0;
}