0% found this document useful (0 votes)
12 views17 pages

CG Lab PV Assignment

The document outlines several assignments from a Computer Graphics course, including tasks such as implementing a ray-tracing renderer, modeling 3D fractal objects, simulating celestial mechanics, creating a cloth simulation, and developing a dynamic water simulation system. Each assignment includes problem statements, aims, objectives, and code snippets demonstrating the implementation of the respective simulations. The focus is on applying physics and graphics concepts to create realistic visual effects and interactions.

Uploaded by

Tript sachdeva
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views17 pages

CG Lab PV Assignment

The document outlines several assignments from a Computer Graphics course, including tasks such as implementing a ray-tracing renderer, modeling 3D fractal objects, simulating celestial mechanics, creating a cloth simulation, and developing a dynamic water simulation system. Each assignment includes problem statements, aims, objectives, and code snippets demonstrating the implementation of the respective simulations. The focus is on applying physics and graphics concepts to create realistic visual effects and interactions.

Uploaded by

Tript sachdeva
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

DEPARTMENT OF

COMPUTER SCIENCE & ENGINEERING

Assignment 2

CG LAB
Student Name: Lakshay Baskotra UID: 22BCS15016
Branch: BE-CSE Section/Group: IOT-605 ‘B’
Semester: 6th Date of Performance: 10/04/2025
Subject Name: Computer Graphics with Lab Subject Code:22CSH-352

Problem Statements : Implement a ray-tracing renderer to simulate realistic lighting effects,


including shadows and reflections.
Aim: To simulate realistic light behavior in computer graphics.
Objective : Understand ray tracing concepts, including intersections, light reflection, and
refraction for photorealistic rendering.

Code :

from PIL import Image


import math

WIDTH, HEIGHT = 400, 300


MAX_DEPTH = 3
BACKGROUND_COLOR = (0, 0, 0)

# Vector utility class


class Vec3:
def init (self, x, y, z): self.x, self.y, self.z = x, y, z
def add (self, o): return Vec3(self.x + o.x, self.y + o.y, self.z + o.z)
def sub (self, o): return Vec3(self.x - o.x, self.y - o.y, self.z - o.z)
def mul (self, s): return Vec3(self.x * s, self.y * s, self.z * s)
def dot(self, o): return self.x * o.x + self.y * o.y + self.z * o.z
def normalize(self): l = math.sqrt(self.dot(self)); return self * (1.0 / l)

# Ray class
class Ray:
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

def init (self, origin, direction):


self.origin, self.direction = origin, direction.normalize()

# Sphere class
class Sphere:
def init (self, center, radius, color, reflection=0.5):
self.center, self.radius, self.color, self.reflection = center, radius,
color, reflection

def intersect(self, ray):


oc = ray.origin - self.center
b = 2.0 * oc.dot(ray.direction)
c = oc.dot(oc) - self.radius * self.radius
discriminant = b * b - 4 * c
if discriminant < 0:
return None
dist = (-b - math.sqrt(discriminant)) / 2.0
return dist if dist > 0 else None

# Light
light_pos = Vec3(5, 5, -10)

# Scene setup
scene = [
Sphere(Vec3(0, -1, 3), 1, (255, 0, 0)), # Red Sphere
Sphere(Vec3(2, 0, 4), 1, (0, 0, 255)), # Blue Sphere
Sphere(Vec3(-2, 0, 4), 1, (0, 255, 0)), # Green Sphere
Sphere(Vec3(0, -5001, 0), 5000, (255, 255, 0)) # Ground
]

def trace(ray, depth):


color = BACKGROUND_COLOR
min_dist = float('inf')
hit_obj = None
for obj in scene:
dist = obj.intersect(ray)
if dist and dist < min_dist:
min_dist = dist
hit_obj = obj

if hit_obj:
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

hit_point = ray.origin + ray.direction * min_dist


normal = (hit_point - hit_obj.center).normalize()
to_light = (light_pos - hit_point).normalize()

# Shadow check
shadow_ray = Ray(hit_point + normal * 0.001, to_light)
in_shadow = any(obj.intersect(shadow_ray) for obj in scene if obj !=
hit_obj)

# Diffuse
intensity = max(normal.dot(to_light), 0) * (0.2 if in_shadow else 1.0)
local_color = tuple(min(int(c * intensity), 255) for c in hit_obj.color)

# Reflection
if depth < MAX_DEPTH and hit_obj.reflection > 0:
reflect_dir = ray.direction - normal * 2 * ray.direction.dot(normal)
reflect_ray = Ray(hit_point + normal * 0.001, reflect_dir)
reflect_color = trace(reflect_ray, depth + 1)
color = tuple(
int(local_color[i] * (1 - hit_obj.reflection) + reflect_color[i]
* hit_obj.reflection)
for i in range(3)
)
else:
color = local_color
return color

# Create image
img = Image.new("RGB", (WIDTH, HEIGHT))
pixels = img.load()

camera = Vec3(0, 0, -1)


for x in range(WIDTH):
for y in range(HEIGHT):
dir_x = (x - WIDTH / 2) / WIDTH
dir_y = -(y - HEIGHT / 2) / HEIGHT
direction = Vec3(dir_x, dir_y, 1)
ray = Ray(camera, direction)
pixels[x, y] = trace(ray, 0)

img.save("raytracing_output.png")
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

print("Image saved as raytracing_output.png")

Output:
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

Ques 2:
Problem Statements: Write a program to model and render a 3D fractal object such as the
Mandelbrot set or a 3D Koch snowflake.

Aim: To explore fractal geometry and its applications in graphics.

Objective: Learn iterative fractal generation techniques and visualize self-similarity properties in
3D.

Code:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Line3DCollection

def koch_snowflake(order, scale=10):


# Initial triangle
p1 = np.array([0, 0])
p2 = np.array([scale, 0])
p3 = np.array([scale / 2, scale * np.sqrt(3) / 2])
points = [p1, p2, p3, p1] # Closed triangle

def divide(points):
new_points = []
for i in range(len(points) - 1):
a = points[i]
b = points[i + 1]
vec = (b - a) / 3
p1 = a + vec
p3 = a + 2 * vec
angle = np.pi / 3
rotation = np.array([
[np.cos(angle), -np.sin(angle)],
[np.sin(angle), np.cos(angle)]
])
p2 = p1 + rotation.dot(vec)
new_points += [a, p1, p2, p3]
new_points.append(points[-1])
return new_points

for _ in range(order):
points = divide(points)
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

return np.array(points)

def extrude_to_3d(points, height=5):


faces = []
for z in [0, height]:
faces.append([(x, y, z) for x, y in points])

return faces
# Generate fractal
order = 3
points = koch_snowflake(order)
faces = extrude_to_3d(points)

# Plot
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111, projection='3d')

for face in faces:


xs, ys, zs = zip(*face)
ax.plot(xs, ys, zs)

# Connect edges between top and bottom


for i in range(len(faces[0])):
x = [faces[0][i][0], faces[1][i][0]]
y = [faces[0][i][1], faces[1][i][1]]
z = [faces[0][i][2], faces[1][i][2]]
ax.plot(x, y, z, color='gray')

ax.set_title("3D Koch Snowflake (Extruded)")


plt.show()
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

OUTPUT:
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

Ques 3:
Problem Statements: Create an interactive simulation of celestial mechanics for planets orbiting
a star system with gravity effects.

Aim: To visualize gravitational force interactions in a dynamic celestial system.

Objective: Apply physics formulas for gravitational forces and simulate realistic orbital paths in
2D or 3D.

Code:

import pygame
import math

# Constants
G = 6.67430e-11 # Gravitational constant
SCALE = 1e-9 # Scale to draw pixels
TIMESTEP = 3600 # One hour per frame

WIDTH, HEIGHT = 800, 800


WHITE = (255, 255, 255)
YELLOW = (255, 255, 0)
BLUE = (100, 149, 237)
GREY = (80, 78, 81)

class Body:
def init (self, x, y, radius, color, mass, name="Planet"):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.mass = mass
self.name = name
self.orbit = []
self.x_vel = 0
self.y_vel = 0

def draw(self, win):


x = self.x * SCALE + WIDTH / 2
y = self.y * SCALE + HEIGHT / 2
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

pygame.draw.circle(win, self.color, (int(x), int(y)), self.radius)

if len(self.orbit) > 2:
updated_points = [
(px * SCALE + WIDTH / 2, py * SCALE + HEIGHT / 2)
for px, py in self.orbit
]
pygame.draw.lines(win, self.color, False, updated_points, 2)

def attract(self, other):


dx = other.x - self.x
dy = other.y - self.y
distance = math.sqrt(dx**2 + dy**2)
force = G * self.mass * other.mass / distance**2
theta = math.atan2(dy, dx)
fx = math.cos(theta) * force
fy = math.sin(theta) * force
return fx, fy

def update_position(self, bodies):


total_fx = total_fy = 0
for body in bodies:
if self == body:
continue
fx, fy = self.attract(body)
total_fx += fx
total_fy += fy

self.x_vel += total_fx / self.mass * TIMESTEP


self.y_vel += total_fy / self.mass * TIMESTEP

self.x += self.x_vel * TIMESTEP


self.y += self.y_vel * TIMESTEP
self.orbit.append((self.x, self.y))

def main():
pygame.init()
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Celestial Simulation")

sun = Body(0, 0, 30, YELLOW, 1.98892e30, "Sun")


DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

earth = Body(1.496e11, 0, 16, BLUE, 5.972e24, "Earth")


earth.y_vel = 29.783e3 # Initial tangential speed

moon = Body(1.496e11 + 384400000, 0, 6, GREY, 7.342e22, "Moon")


moon.y_vel = 29.783e3 + 1.022e3 # Earth's speed + Moon's speed

bodies = [sun, earth, moon]

clock = pygame.time.Clock()
run = True

while run:
clock.tick(60)
win.fill((0, 0, 0))

for event in pygame.event.get():


if event.type == pygame.QUIT:
run = False

for body in bodies:


body.update_position(bodies)
body.draw(win)

pygame.display.update()

pygame.quit()

if name == " main ":


main()
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

Output:

Ques4:
Problem Statement: Develop a cloth simulation that reacts to user inputs and simulates realistic
fabric behavior.
Aim: To simulate flexible materials using physics- based techniques.
Objective: Learn to model forces like tension, shear, and gravity to create realistic cloth
simulations.

Code:
import pygame
import math

WIDTH, HEIGHT = 800, 600


DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

ROWS, COLS = 30, 40


SPACING = 15
GRAVITY = 0.5
FRICTION = 0.99
CONSTRAINT_ITERATIONS = 5

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Cloth Simulation")

class Point:
def init (self, x, y, pinned=False):
self.x = x
self.y = y
self.old_x = x
self.old_y = y
self.pinned = pinned
self.constraints = []

def update(self):
if self.pinned:
return
dx = (self.x - self.old_x) * FRICTION
dy = (self.y - self.old_y) * FRICTION

self.old_x = self.x
self.old_y = self.y

self.x += dx
self.y += dy + GRAVITY

def constrain(self):
for c in self.constraints:
c.solve()

def attach(self, other):


self.constraints.append(Constraint(self, other))

def draw(self, surface):


pygame.draw.circle(surface, (255, 255, 255), (int(self.x), int(self.y)),
2)
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

class Constraint:
def init (self, p1, p2):
self.p1 = p1
self.p2 = p2
self.length = math.dist((p1.x, p1.y), (p2.x, p2.y))

def solve(self):
dx = self.p2.x - self.p1.x
dy = self.p2.y - self.p1.y
dist = math.sqrt(dx**2 + dy**2)
diff = (self.length - dist) / dist

offset_x = dx * 0.5 * diff


offset_y = dy * 0.5 * diff

if not self.p1.pinned:
self.p1.x -= offset_x
self.p1.y -= offset_y
if not self.p2.pinned:
self.p2.x += offset_x
self.p2.y += offset_y

points = []

# Initialize grid of points


for y in range(ROWS):
row = []
for x in range(COLS):
point = Point(x * SPACING + 100, y * SPACING + 20, pinned=(y == 0 and x %
5 == 0))
row.append(point)
if x > 0:
point.attach(row[x - 1])
if y > 0:
point.attach(points[y - 1][x])
points.append(row)

def draw_lines(surface):
for row in points:
for point in row:
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

for c in point.constraints:
pygame.draw.line(surface, (100, 255, 100),
(int(c.p1.x), int(c.p1.y)),
(int(c.p2.x), int(c.p2.y)), 1)

def update_cloth():
for row in points:
for point in row:
point.update()
for _ in range(CONSTRAINT_ITERATIONS):
for row in points:
for point in row:
point.constrain()

clock = pygame.time.Clock()
running = True
while running:
clock.tick(60)
screen.fill((30, 30, 30))

for event in pygame.event.get():


if event.type == pygame.QUIT:
running = False

update_cloth()
draw_lines(screen)
for row in points:
for point in row:
point.draw(screen)

pygame.display.flip()

pygame.quit()

Output:
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

Ques 5:
Problem Statements : Build a dynamic water simulation system that uses particle or grid-based
methods to depict fluid motion.
Aim: To simulate realistic water motion using computational techniques.
Objective: Understand fluid dynamics principles and their implementation in real-time
simulations.

Code:

import pygame
import random
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

import math

# Initialize Pygame
pygame.init()

# Window settings
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("💧 Water Simulation - Particle Based")

# Colors
BLUE = (0, 120, 255)
BLACK = (0, 0, 0)

# Physics constants
GRAVITY = 0.3
FRICTION = 0.98
NUM_PARTICLES = 300

class Particle:
def init (self, x, y):
self.x = x
self.y = y
self.radius = 3
self.color = BLUE
self.vx = random.uniform(-1, 1)
self.vy = random.uniform(-1, 0)

def move(self):
self.vy += GRAVITY
self.vx *= FRICTION
self.vy *= FRICTION
self.x += self.vx
self.y += self.vy

# Bounce on edges
if self.x <= 0 or self.x >= WIDTH:
self.vx *= -1
if self.y >= HEIGHT - self.radius:
self.vy *= -0.6
self.y = HEIGHT - self.radius
DEPARTMENT OF
COMPUTER SCIENCE & ENGINEERING

def draw(self, screen):


pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)),
self.radius)

# Create particles
particles = [Particle(random.randint(300, 500), random.randint(100, 200)) for _
in range(NUM_PARTICLES)]

# Main loop
running = True
clock = pygame.time.Clock()

while running:
screen.fill(BLACK)

for event in pygame.event.get():


if event.type == pygame.QUIT:
running = False

for p in particles:
p.move()
p.draw(screen)

pygame.display.flip()
clock.tick(60)

pygame.quit()

Output:

You might also like