DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
COMPLEX PROBLEMS
CG LAB
Student Name: nemesis UID:
22BCS16….. Section/Group: AIT-2
Date :10-04-25
Q1 .
Generate a dynamic analog clock with ticking second, minute, and hour hands.
Implemetation/Code
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#include <dos.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
void calculate_hand_pos(int cx, int cy, int radius, double angle_deg, int &x, int &y)
{ double angle_rad = (90.0 - angle_deg) * M_PI / 180.0;
x = cx + (int)(radius * cos(angle_rad));
y = cy - (int)(radius * sin(angle_rad));
}
int main() {
int gd = DETECT, gm;
initgraph(&gd, &gm, "C:\\TurboC3\\BGI");
int mid_x = getmaxx() / 2;
int mid_y = getmaxy() / 2;
int clock_radius = (getmaxy() < getmaxx() ? getmaxy() : getmaxx()) / 3;
int hour_hand_len = (int)(clock_radius * 0.5);
int min_hand_len = (int)(clock_radius * 0.7);
int sec_hand_len = (int)(clock_radius * 0.9);
int hx, hy, mx, my, sx, sy;
time_t raw_time;
struct tm *current_time;
while (!kbhit()) {
time(&raw_time);
current_time = localtime(&raw_time);
int hours = current_time->tm_hour;
int minutes = current_time->tm_min;
int seconds = current_time->tm_sec;
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
double sec_angle = seconds * 6.0;
double min_angle = (minutes + seconds / 60.0) * 6.0;
double hour_angle = ((hours % 12) + minutes / 60.0) * 30.0;
calculate_hand_pos(mid_x, mid_y, sec_hand_len, sec_angle, sx, sy);
calculate_hand_pos(mid_x, mid_y, min_hand_len, min_angle, mx, my);
calculate_hand_pos(mid_x, mid_y, hour_hand_len, hour_angle, hx, hy);
cleardevice();
setcolor(WHITE);
circle(mid_x, mid_y, clock_radius);
setcolor(YELLOW);
for (int i = 0; i < 12; ++i) {
int start_x, start_y, end_x, end_y;
double marker_angle_deg = i * 30.0;
calculate_hand_pos(mid_x, mid_y, (int)(clock_radius * 0.9), marker_angle_deg,
start_x, start_y);
calculate_hand_pos(mid_x, mid_y, clock_radius, marker_angle_deg, end_x, end_y);
line(start_x, start_y, end_x, end_y);
}
setcolor(WHITE);
circle(mid_x, mid_y, 3);
floodfill(mid_x, mid_y, WHITE);
setcolor(LIGHTBLUE);
setlinestyle(SOLID_LINE, 0, THICK_WIDTH);
line(mid_x, mid_y, hx, hy);
setcolor(GREEN);
setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
line(mid_x, mid_y, mx, my);
setcolor(RED);
line(mid_x, mid_y, sx, sy);
delay(100);
}
getch();
closegraph();
return 0;
}
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
Q2 .
Implement an interactive tool to draw concentric circles using the midpoint algorithm with
dynamic radius input.
Implemetation/Code
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
void plot_circle_points(int xc, int yc, int x, int y, int color)
{ putpixel(xc + x, yc + y, color);
putpixel(xc - x, yc + y,
color); putpixel(xc + x, yc -
y, color); putpixel(xc - x, yc -
y, color); putpixel(xc + y, yc
+ x, color); putpixel(xc - y,
yc + x, color); putpixel(xc +
y, yc - x, color); putpixel(xc -
y, yc - x, color);
}
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
void drawCircleMidpoint(int xc, int yc, int r, int color)
{ if (r <= 0) return;
int x = 0;
int y = r;
int p = 1 -
r;
plot_circle_points(xc, yc, x, y, color);
while (x < y) {
x++;
if (p < 0) {
p = p + 2 * x + 1;
} else
{ y--
;
p = p + 2 * (x - y) + 1;
}
plot_circle_points(xc, yc, x, y, color);
}
}
int getRadiusInput(int prompt_x, int prompt_y) {
char input_buffer[10];
int buffer_index = 0;
char display_char[2] = {0};
int current_input_x = prompt_x;
memset(input_buffer, 0, sizeof(input_buffer));
setfillstyle(SOLID_FILL, BLACK);
int clear_y = prompt_y;
int clear_height = textheight("M") + 5;
int clear_width = getmaxx() - prompt_x - 10;
bar(prompt_x, clear_y, prompt_x + clear_width, clear_y + clear_height);
setcolor(YELLOW);
outtextxy(prompt_x, prompt_y, "Enter Radius (1-300, Esc=Exit): ");
current_input_x += textwidth("Enter Radius (1-300, Esc=Exit): ");
while (buffer_index < sizeof(input_buffer) - 1) {
int key =
getch(); if (key
== 27) {
return 0;
} else if (key == 13) {
if (buffer_index > 0)
{ break;
}
return 0;
} else if (key == 8 && buffer_index > 0)
{ buffer_index--;
input_buffer[buffer_index] = '\0';
setcolor(BLACK);
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
display_char[0] = 'W';
int char_width = textwidth(display_char);
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
current_input_x -= char_width;
if (current_input_x < 0) current_input_x = 0;
bar(current_input_x, prompt_y, current_input_x + char_width, prompt_y + textheight("0"));
} else if (isdigit(key) && buffer_index < sizeof(input_buffer) - 1)
{ input_buffer[buffer_index] = (char)key;
buffer_index++;
input_buffer[buffer_index] = '\0';
setcolor(WHITE);
display_char[0] = (char)key;
outtextxy(current_input_x, prompt_y, display_char);
current_input_x += textwidth(display_char);
}
}
input_buffer[buffer_index] = '\0';
if (strlen(input_buffer) > 0) {
int radius = atoi(input_buffer);
if (radius > 0 && radius < 32767) {
return radius;
}
}
return 0;
}
int main() {
int gd = DETECT, gm;
initgraph(&gd, &gm, "C:\\TURBOC3\\BGI");
int errorcode = graphresult();
if (errorcode != grOk) {
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Please ensure the BGI path in initgraph is correct for your system.\
n"); printf("Press any key to halt:");
getch();
exit(1);
}
int mid_x = getmaxx() /
2; int mid_y = getmaxy()
/ 2; int radius = 0;
int prompt_x =
10; int prompt_y
= 10;
int status_y = prompt_y + 20;
do {
radius = getRadiusInput(prompt_x, prompt_y);
if (radius > 0) {
setcolor(WHITE);
drawCircleMidpoint(mid_x, mid_y, radius, WHITE);
setfillstyle(SOLID_FILL, BLACK);
int status_clear_width = getmaxx() - prompt_x - 10;
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
bar(prompt_x, status_y, prompt_x + status_clear_width, status_y + textheight("M"));
char radius_text[30];
sprintf(radius_text, "Drew Radius: %d. Press key...", radius);
setcolor(LIGHTGREEN);
outtextxy(prompt_x, status_y, radius_text);
getch();
} else {
break;
}
} while (radius > 0);
cleardevice();
setcolor(YELLOW);
outtextxy(mid_x - textwidth("Exiting...")/2, mid_y, "Exiting...");
closegraph();
return 0;
}
Q3.
Implement a multi-viewport display that shows the same object in different viewports
(scaled, translated, rotated).
Implemetation/Code
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
typedef struct
{ double x, y;
} Point;
Point rotate_point(Point p, double angle_deg, double cx, double cy)
{ double angle_rad = angle_deg * M_PI / 180.0;
double cos_a = cos(angle_rad);
double sin_a = sin(angle_rad);
Point rotated_p;
double temp_x = p.x - cx;
double temp_y = p.y - cy;
rotated_p.x = temp_x * cos_a - temp_y * sin_a;
rotated_p.y = temp_x * sin_a + temp_y * cos_a;
rotated_p.x += cx;
rotated_p.y += cy;
return rotated_p;
}
Point scale_point(Point p, double sx, double sy, double cx, double cy)
{ Point scaled_p;
double temp_x = p.x - cx;
double temp_y = p.y - cy;
scaled_p.x = temp_x * sx;
scaled_p.y = temp_y * sy;
scaled_p.x += cx;
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
scaled_p.y += cy;
return scaled_p;
}
Point translate_point(Point p, double tx, double ty) {
Point translated_p;
translated_p.x = p.x + tx;
translated_p.y = p.y + ty;
return translated_p;
}
void draw_shape(Point points[], int num_points, int color)
{ if (num_points < 2) return;
int poly_points[20];
if (num_points * 2 + 2 > 20) return;
for (int i = 0; i < num_points; ++i)
{ poly_points[i * 2] = (int)(points[i].x + 0.5);
poly_points[i * 2 + 1] = (int)(points[i].y +
0.5);
}
poly_points[num_points * 2] = poly_points[0];
poly_points[num_points * 2 + 1] = poly_points[1];
setcolor(color);
drawpoly(num_points + 1, poly_points);
}
int main() {
int gd = DETECT, gm;
initgraph(&gd, &gm, "C:\\TURBOC3\\BGI");
int errorcode = graphresult();
if (errorcode != grOk) {
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Please ensure the BGI path in initgraph is correct for your system.\n");
printf("Press any key to halt:");
getch();
exit(1);
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
}
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
const int num_vertices = 3;
Point base_object[num_vertices] = {
{0, -30},
{-25, 20},
{25, 20}
};
Point transformed_object[num_vertices];
int screen_w = getmaxx();
int screen_h = getmaxy();
int vp_w = screen_w / 2;
int vp_h = screen_h / 2;
int vp[4][4] = {
{0, 0, vp_w - 1, vp_h - 1},
{vp_w, 0, screen_w - 1, vp_h - 1},
{0, vp_h, vp_w - 1, screen_h - 1},
{vp_w, vp_h, screen_w - 1, screen_h - 1}
};
for (int i = 0; i < 4; ++i)
{ int j;
int x1 = vp[i][0];
int y1 = vp[i][1];
int x2 = vp[i][2];
int y2 = vp[i][3];
int current_vp_w = x2 - x1 + 1;
int current_vp_h = y2 - y1 + 1;
double vp_cx = (double)current_vp_w / 2.0;
double vp_cy = (double)current_vp_h / 2.0;
for (j = 0; j < num_vertices; ++j)
{ transformed_object[j] = base_object[j];
}
switch (i)
{ case 0:
break;
case 1:
DEPARTMENT OF
COMPUTER SCIENCE &
ENGINEERING
for (j = 0; j < num_vertices; ++j) {
transformed_object[j] = scale_point(transformed_object[j], 1.5, 1.5, 0, 0);
}
break;
case 2:
for (j = 0; j < num_vertices; ++j) {
transformed_object[j] = rotate_point(transformed_object[j], 45.0, 0, 0);
}
break;
case 3:
for (j = 0; j < num_vertices; ++j) {
transformed_object[j] = scale_point(transformed_object[j], 0.7, 0.7, 0, 0);
transformed_object[j] = translate_point(transformed_object[j], -15, -10);
}
break;
}
for (j = 0; j < num_vertices; ++j) {
transformed_object[j] = translate_point(transformed_object[j], vp_cx, vp_cy);
}
setviewport(x1, y1, x2, y2, 1);
setcolor(DARKGRAY);
rectangle(0, 0, current_vp_w - 1, current_vp_h - 1);
draw_shape(transformed_object, num_vertices, WHITE);
char info[10];
sprintf(info, "VP %d", i + 1);
setcolor(YELLOW);
outtextxy(5, 5, info);
}
setviewport(0, 0, screen_w - 1, screen_h - 1, 1);
getch();
closegraph();
return 0;
}