Hi! Scroll down to see fun stuff ↓


I'm a Computer Graphics Master's student at University of Pennsylvania specializing in math & simulation. Below are projects I worked on throughout my years at UPenn and as a mathematics undergrad at NYU!

TikTokYouTubeGitHubInstagram

Energy Based Partial Keyframe Houdini Authoring Tool

As a part of my Advanced Computer Graphics course at UPenn, I worked with a fellow student to bring the 2014 SIGGRAPH paper "Animating Deformable Objects using Sparse Spacetime Constraints" by Christian Schulz, et al. to life as a Houdini authoring tool which takes a tetrahedral mesh and "partial keyframes" as input, and uses an energy optimization based approach to output a smooth, spring-like motion that interpolates the partial keys and respects pin constraints. The paper left out some precise details, so it made for an interesting problem to figure out how to numerically minimize the integral quantity up to a desired resolution using linear algebraic tricks. Our end results are satisfying, and I got to learn a lot about optimization, eigenmodes & mass/stiffness matrices along the way!

Video explanation and demo of the method and our Houdini tool. (Skip to 3:15 for our preliminary tests in Python of the core algorithm, 6:45 for some partially keyframed animated demos in Houdini!)

Monte-Carlo Path Tracing Experiments

Last semester, I challenged myself to understand the Light Transport Equation (LTE) in greater depth. After many hours of reading through the PBRT book and watching lectures from Prof. Crane on YouTube, I developed a satisfying understanding of the LTE. Some key insights were: 1) The LTE can be Neumann-Expanded into an "Integral over paths" formulation, from which the traditional Path-Tracing algorithm naturally falls out! 2) Russian Roulette is a technique used not just for minimizing computational effort on low contributing rays, but also to provably reduce bias in the rendering algorithm. I used all my new knowledge to write a Path-Tracer from scratch in ShaderToy (live link: https://www.shadertoy.com/view/msB3Dh). Below are intermediary renders from the step-by-step progress of this personal exploration that ultimately led me to the final result.

Video showcasing various intermediary results which ultimately led up to a path-tracer.

2D Jacobian Based Inverse Kinematics

Last semester, I decided to take a deep dive to understanding the Jacobian pseudoinverse based IK, and the corresponding null-space operator in order to implement a 2D robotic arm that: 1) Reaches its target position, and 2) Avoids contact with another position, provided enough slack to do so. I used this demonstration to help students better understand IK during my office hours as a T.A. for our CIS562 Computer Animation class. Later, I went on to use my IK solver to make a 2D spline based character gait-animator (see next slide).

Demonstration of my IK solver, with projection of collision constraint into the Jacobian null-space.

Splines and Character Gait Animator

From my new knowledge on FKIK, I decided to explore explore splines to make a 2D keyframe character animator. I used it to animate 3 different walk cycles with respect to an orange square's local frame that I move each frame to turn it into a continuous cycle. The joints can be manipulated in an FK mode and an IK mode, the keyframe timings can be adjusted by clicking and dragging, the joint angles are interpolated using Cubic Cardinal Splines of varying tension, and I save the animations into a textfile in order to reopen them. Future work: Blend together many of these motion gaits to create a playable character that seemlessly blends between the gait types depending on the input!

2D Character Animator Demo in Python (skip to 0:34 to see three animations I made using this tool, i.e. IDLE, WALKING, RUNNING)

Spline editor I made while learning about various point interpolation / approximation schemes.

Mass-Spring Cloth Simulation

My first exposure to Computer Graphics was in Prof. Daniele Panozzo's course at NYU, where I chose cloth simulation as my final project. The implementation is a mass-spring-damper model, and rendered using ray-tracing. The cloth is a lattice of vertices with springs attached between neighbors (diagonal neighbors too, so it doesn't collapse in on its faces), with two of its corners pinned. There is a constant gravitational force and air-drag, the latter of which helped achieve better numerical stability. In the animation, the top left corner moves back and forth and we observe the rippling effect on the rest of the cloth.

Integrated via Forward Euler's Method (for small h, but here it's sped up).

Malkus Chaotic Water Wheel Simulation

The Malkus Water Wheel is a great example of a dynamical system that exhibits chaotic behavior. It is a water wheel with n equally spaced buckets along the circumference of the wheel. Water fills at a fixed rate into any bucket that reaches the top, and all the buckets leak water at a fixed (slow) rate as well. Furthermore, the wheel has frictional dampening. These 3 components (fixed fill rate, fixed leak rate, and friction) make the movement of the wheel chaotic. Today, my animation is on the "Malkus Waterwheel" Wikipedia page as well: https://en.wikipedia.org/wiki/Malkus_waterwheel, and a TikTok in which I demonstrated the simulations currently sits at 60K views.

Simulation of the Lorenz Water Wheel (Plotted is the center of mass of all the water distributed in the system across the cups.)

We let the simulation run for a long while and see what the plot of the center of mass looks like, against the angular velocity of the wheel. We clearly see chaotic behavior, and the 2 attractors of the system!

Rigid Body Collision

Implementing a rigid body simulator has always been a long-standing goal of mine, but wasn't exactly sure how to go about doing this. I had tried to manipulate the conservation of energy and momenta equations, but that didn't really get me anywhere. After some research, I came across a wonderful impulse based approach by Jim Van Verth (http://www.essentialmath.com/AngularImpulse.pdf) that used the coefficient of restitution formula and relative velocities at the collision normal to achieve this. At first, I was unsatisfied by this because I couldn't see how this was equivalent to the conservation formulae, but after some thinking I was able to prove it!

Impulse based response from an earlier exploration (winter 2021-22).

More recent demo with gravity and separating planes.

Lego Mini-Minecraft in C++!

Final project in CS560 Interactive Computer Graphics course at UPenn. (Made using Qt creator & OpenGL.) We worked as a team of three, and my role was mainly working on the procedural terrain generation, which is done using a combination of noise functions such as Worley, Perlin, and Fractal Noise (FBM). We added three unique terrains (dessert, hills, and mountains), along with cave systems underground and clouds.

Video demo of our Mini-Minecraft Project.

Cube Balancing Magic Plate

As I was browsing YouTube one day, I came across a mechanical plate powered by several actuators that seemed to magically balance a ball on top and even move it along any desired trajectories. I was really impressed by this — it seemed like such a difficult task! Using the PD control theory techniques I learned in my Computer Animation class at UPenn (which I then went on to T.A.), today I am proud to share that I was able to simulate this system on my own in Python! In the simulation, the cyan leg is fixed, but the two blue legs are extended and retracted based on how the plate should move to bring the cube to the pink target circle at each time step.

Video demo of Cube-Plate Balancer. I set the target trajectory to various paths, and in each case we see the plane properly tilts so the cube "magically" follows the target (pink dot).

I Joined A Fun TikTok Niche :)

On TikTok, there is a fantastic niche of syncing math animations to music, which I recently decided to contribute to. Here are a few of my contributions ("Perspective Trick", "Sum of Squares", and "Color Gradient Magic"), which together have amassed nearly a million views! These were all made programmatically in Python. Scroll down to see more of my animations!

Left: Titled "Perspective Trick", it's an animation demonstrating the equivalence between the conic sections in Projective Geometry. Center: Sum of squares animation. Right: A demonstration of how color can be interpolated in a triangle with barycentric coordinates using the areas of three sub-triangles.

Inverse Transform Sampling Animation

Animation I made explaining and demonstrating the inverse transform sampling method in Probability. This one currently sits at 13K views on TikTok, where I added my voiceover explaining the concept while the animation is playing too.

Left: Titled "Perspective Trick", it's an animation demonstrating the equivalence between the conic sections in Projective Geometry. Center: Sum of squares animation. Right: A demonstration of how color can be interpolated in a triangle with barycentric coordinates using the areas of three sub-triangles.

Pendulums Paint Bottle Animation (Lissajous Curves)

In this animation, there is a pair of coupled pendulums swinging in 3D space. The first one swings only on the xz-plane, which the other one is attached to the bottom of the first one and swings in a plane perpendicular to the xz-plane, but parallel to the yz-plane. We imagine an open paint bottle attached to the bottom of the second pendulum and plot where the paint spills on the ground (the xy-plane). The resulting plot is a "Lissajous Curve", which arises whenever the components of a parametric function are periodic with different periodicity.

"Lissajous Curve" 3D Animation

Shader Fun!

As part of my CS560 Interactive Computer Graphics class at UPenn, I implemented various Vertex, Fragment, and Post-processing shaders in OpenGL.

Mario being tortured by various surface and post-processing shaders.

Perspective Projection and Raycasting

Using my knowledge of Linear Algebra, I implemented a 3D to 2D perspective projection function. In particular, given a point (x,y,z) in 3-dimensional space, I derived the equations for drawing this point on the 2-dimensional screen, as if it were seen from an eye that perceives perspective. I use this function all the time now to quickly implement my 3D project ideas, such as the Lissajous pendulum animation or PD cube-plate balancer.

3D Perspective Projection of Axes and a Cube

3D Projection of a UV-Sphere

Some More Fun Animations :)

DVD Logo Bouncing Animation

Animation of a Deterministic Finite Automaton that recognizes the language of all strings containing 2 adjacent a's, over the alphabet {a,b}.

Curves and Spline Surfaces

My first research project experience with Prof. Teseo Schneider from the University of Victoria involves the construction of B-spline surfaces from quadrilateral meshes, for use in isogeometric analysis. I had never dealt with B-splines and curve drawing techniques in general prior to this, so I decided to experiment with these on my own. First, I created a program that draws smooth curves that fit a collection of user-placed points, using a variety of different methods the user can toggle between. Later, I extended this to rendering 2D B-spline surfaces that can be manipulated using control points.

Interpolation & approximative curve drawing spheres, and B-spline surface implementation in Python.

N-Body Simulation

The famous n-body simulation in computational physics involves simulating the trajectories of massive bodies under the influence of their own gravitational fields. The trajectories are quite unpredictable and chaotic.

N-body Simulation in 2D. First, we show 5 masses interacting with an arbitrary initalization. Then, we have a small planetary system.

N-body simulation in 3D. (Using 3D projection.)

K-means Algorithm Animation

Given k clusters of sample data, the k-means algorithm is a method to iteratively find a classifier that classifies new data points into one of k clusters. The algorithm is quite simple. It initializes k "centroids", and repeats the following until convergence: 1. For each centroid (the white rectangles in the animation) find those sample points which are closest to that centroid (relative to the other centroids). 2. Calculate the center of mass of this subset of "closest" points. 3. Once k center of mass locations (the red crosses in the animation) have been computed (one for each centroid), we simultaneously move each of the to these locations. If all the centoids converge to some locations, we classify a new data point to fall in the i-th cluster if and only if it is closest to the i-th centroid.

K-Means Algorithm Instance that converges. I tried looking into drawing the final decision boundary, but the algorithms to draw it were suprisingly more complex (and brilliant!) than expected. Perhaps will implement in the future :)

iOS Game: U.D.L.R.

U.D.L.R. is a mini game I made for iOS devices involving smashing away circles in the correct direction as they appear from the top of the screen fast and faster. It was my first experience programming in Apple's Swift language and I wanted to see what it was like publishing an actual app on the AppStore. I had a lot of fun coding it up, designing the logo, and the putting together the music for each level in Garageband (and seeing my friends and family waste their time on my game)! AppStore link: https://apps.apple.com/us/app/u-d-l-r/id1330499105

U.D.L.R. gameplay on an iPhone X.

Dr. Doofenshmirtz Twitter Bot!

I made a silly Twitter bot (https://twitter.com/doofinator_) in Python that looks through a list of common english words and tweets a Google Image of that search query, with the text "Ah, a  [search-query]". After 10 minutes, it follows up with a second tweet containing the same image but superimposed with an image of Perry the Platypus's hat at an appropriate location and size, along with the text "PERRY THE [SEARCH QUERY]!?!". This is meant to emulate evil scientist Dr. Heinz Doofenshmirtz from the T.V. show Phineas and Ferb, who fails to recognize his platypus nemesis Perry without his hat. Recently, I made a TikTok video explaining this bot which gained decent traction (10K views, 2.5K likes) and somewhat boosted the bot's popularity. More to come from this bot in the future :))

Sample Tweets from the Bot, for the search terms "brain", "cane", "bulb", and "blender".

Binary Symbol Classifier

I was always fascinated by artifical neural networks and machine learning in general. I wrote a neural network that learns from previous drawings to distinguish between two arbitrary symbols.

Here, the network has learned to distinguish between an 'X' and an 'O'. In the video, I draw each symbol and ask it what I've drawn. The program finds the bounding box of the drawing and sends a low resolution version of the picture to the network, which outputs the probabilities that the symbol is an 'X' or an 'O'.

Another example on two symbols from the Devanagari Script which look similar, but the network has learned to distinguish between them.

Fun Desktop Games and Programs!

I started programming when I reached highschool, where I first learned Pascal, and then Java. Since then, I've always enjoyed writing small games or applications for my desktop. Projects like these first got me very interested in programming :)

I had made a recreation of the Flash game "This is the only level" as a programming challenge when I was first learning Java. I had also recreated the Flash game "Gravity Guy" and a side-scroller like Mario.

Recreation of the snake from the online game Slither.io. I used to play this game a lot back in the day...

Flipnote Animator

When I was in elementary school, I used to love using Post-It note stacks to make animations. This is why when I got a Nintendo DS for Christmas one year, I was excited to find out there was a similar app called Flipnote on the device which allowed you to create animations in a similar way. I recreated a similar application for Android (Java) in highschool, and now in Python for my desktop :)

<20 frame animation of guy jumping off cliff with a parachute. When editing a frame in the animation, the Nintendo DS app would allow you to faintly "see though" the Post-It layers into previous frames. I replicated this effect in my program. Also, getting the drawing to work so that it doesn't look 'chunky' when I draw fast was a bit of a (mathy?) challenge.