Introduction
This software considers bending forces, twisting forces, and an optional gravity force to model discrete elastic rod visualized in OpenGL. To implement the constraint that edge lengths remain constant, a stretching force is also implemented. Besides the added forces, the lab improves on last week's in several ways. First, the rotation gesture was made a bit more intuitive. Second, I replaced the force implementing the stretching constraint to weight smaller edge's forces higher because I wanted to punish small edges that became a certain amount larger more than large edges that became the same amount larger. Third and most imortantly, I replaced the Euler integrator with a Runge-Kutta integrator that converges faster and allows me to use a smaller timestep while retaining stability.
User Interface
This lab uses GLUT, which means the user interface is not nearly as intuitive or powerful as the Cocoa apps.

Mouse interaction:
Click and drag the left mouse button to rotate around the origin. Click and drag the right mouse button to translate the object. Clicking and dragging the right mouse button while holding down shift translates on a different axis. These controls are still rather unintuitive, but are slightly better than last week.

Key interaction:
Press 'c' to toggle recording to ppm files named frame#.ppm in the working directory.
Press 'r' to reset the vertices to their input-file-specified locations.
Press 'f' to toggle display of the bending, stretching, and twisting force vectors.
Press 'g' to toggle gravity forces on the vertices.
Press 'v' to toggle showing vertices.
Press 'q' to get out when you become bored.
Input File Format and Examples
The input files consist of a gravity vector (x, y, z), a twisting amount (theta_n - theta_0), and then list of quadruplets, one per line, that describe each vertex: x, y, z, followed by a boolean value indicating whether the vertex is fixed or not (1 means fixed, 0 means unfixed). Here is an example input using just basic bending forces (no twisting), and the resulting output movie:
circle_unwind.txt: 1 0 0 0.0 0 2 0 0 0.000000 1.755165 0.958851 0 0.000000 1.080605 1.682942 0 0.000000 0.141474 1.994990 0 0.000000 -0.832294 1.818595 0 0.000000 -1.602287 1.196944 0 0.000000 -1.979985 0.282240 0 0.000000 -1.872913 -0.701566 0 0.000000 -1.307287 -1.513605 0 0.000000 -0.421592 -1.955060 0 0.000000 0.567324 -1.917849 0 0.000000 1.417340 -1.411081 0 0.000000 1.920341 -0.558831 0 0 2 0 0

Gravity Forces
The following video demonstrates the effect of gravity forces applied perpendicularly to a rod with two fixed endpoints. As expected, the rod sags, suspended at the fixed points.


Twisting Forces
The following three videos demonstrate the effect of twisting forces. The first two videos mimic the setup of Figure 9 in the paper by Bergou et. al. Of course, because I do not detect edge collisions, I cannot achieve the exact same results. However, given the twisting behavior, it seems reasonable that I would get something similar to Figure 9 if the edges were prevented from passing trhough each other. The first demonstrates the effect of a relatively low twisting force, while the second demonstrates a stronger force.


The third movie mimics (or attempts to mimic) the behavior in Figure 8 of Bergou et. al. Again, the lack of collision detection prevents matching the behavior exactly, but my implementation appears to give reasonable results. While I was recording the video I manually moved the ring around so that it could be seen from different angles. This is the cause of the jerky motions.

Miscellaneous Utilities
I have small utilities for creating the input files used above and for proceessing the .ppm files captured from OpenGL in capture mode.

To create the input files, run:
> make TestFiles
This will generate all the text files using generate_test_files.c.

The utilities to process the .ppm files are process_capture.sh and process_capture_nocrop.sh. They both convert all the .ppms in the current directory into pngs that can be stitched together by Quicktime Pro. The difference is process_capture.sh crops the frames to the region in which most of my test files appear, while process_capture_nocrop.sh converts the frames without modification.

For example, you can run:
> ./process_capture.sh
in the directory holding all the frame*.ppm files to crop them and convert them all into pngs stored in frame*.ppm.png.
Obtaining
This program is written in C++ using GLUT. It should compile on most Linux, Windows, and Mac OS X machines if the proper libraries are installed. You should be able to run the program by running:
> make > ./elasticRods window_width window_height timeStep lambda input_filename
Where timeStep is the step size used by the Runge-Kutta integrator, and lambda sets the ratio of the total stretching forces to the total bending + twisting forces.

Lambda typically should just be 1.0, and the step size will be around 1e-4. In some cases, the step size can be made larger while retaining stability, and in others it might need to be made smaller. It all depends on the input configuration.

As usual, please be aware that this is by no means polished software; it was written for a weekly assignment.
Design and code ©2012 Julian Panetta
Valid HTML 4.01 Strict