For this assignment, you will create an OpenGL program that shows a continuously moving marker animated along a spline path between randomly placed control points. Think of it as a buzzing bee or gnat.
Your path should be defined using a cubic Catmull-Rom spline. Each segment of the curve is defined by four random control points: the point before the current segment (p_{0}), the beginning the segment (p_{1}), the end of the segment (p_{2}), and the point after the current segment (p_{3}). Given those four points, spline is defined over a segment from t=0 to t=1 by these four conditions:
p(0) = p_{1} | = position_{} at t=0 |
p(1) = p_{2} | = position_{} at t=1 |
p'(0) = (p_{2} – p_{0})/2 | = derivative_{} at t=0 |
p'(1) = (p_{3} – p_{1})/2 | = derivative at t=1 |
At the end of that segment, the old p_{1} becomes the new p_{0}, the old p_{2} becomes the new p_{1}, the old p_{3} becomes the new p_{2}, and a new random point is introduced as the new p_{3}. The time scale should be one second per unit of t.
You should toggle between two display modes with the 'p' key. In the first mode, you should show the current four control points as Marker objects, with a fifth marker point showing the position as it interpolates along the spline. When the spline segment ends, one control point will disappear and a new one will be randomly generated. The second mode, just show the moving Marker, but not the control point markers.
Implement a third mode with a large cloud of moving markers, each with its own set of random control points.
For up to 25 points of extra credit, add an additional mode that also displays your asteroid from assignment 4, and has the marker randomly orbiting around it. For this mode, and this mode only, your control points should be uniformly distributed over a sphere. Given two ordinary random numbers, you can get points that uniformly cover a sphere (without bunching at the poles) by using one random number for z (scaled to cover -1 to 1) and the other for theta (scaled to cover 0 to 2*pi), giving a random point
(sqrt(1-z*z) * cos(theta), sqrt(1-z*z) * sin(theta), z)
In this mode, you will evaluate the spline using deCasteljau's algorithm and successive steps of spherical linear interpolation. A spherical linear interpolation blends between two points on the sphere, stepping uniformly in angle and keeping all of the interpolated points on the surface of the sphere. It is defined as:
slerp(p_{a}, p_{b}, t) = p_{a}*sin(s*(1-t)) / sin(s) + p_{b}*sin(s*t) / sin(s)
where s = acos(dot(p_{a}, p_{b}))
For deCasteljau's algorithm, you first need to construct a new set of four points on the sphere, q_{0}..q_{3}:
q_{0} = p_{1} |
q_{1} = normalize(–p_{0}/6 + p_{1} + p_{2}/6) |
q_{2} = normalize(p_{1}/6 + p_{2} – p_{3}/6) |
q_{3} = p_{2} |
Given these points, instead of direclty evaluating the spline, you first use spherical linear interpolation between each pair of points:
q_{a} = slerp(q_{0}, q_{1}, t) |
q_{b} = slerp(q_{1}, q_{2}, t) |
q_{c} = slerp(q_{2}, q_{3}, t) |
Then between each of those pairs
q_{d} = slerp(q_{a}, q_{b}, t) |
q_{e} = slerp(q_{b}, q_{c}, t) |
And finally between the last two points
p = r * slerp(q_{d}, q_{e}, t) |
Extra credit is only available if you submit by the original deadline or use your free late. If you submit late with the late penalty, you will not be eligible for any extra credit points. Also, you will only be considered for extra credit if you mention your extra credit work in your readme.
Turn in this assignment electronically by checking your source code into your assn6 CVS directory by 11:59 PM on the day of the deadline. Do your development in the assn6 directory so we can find it. As always, double check that you have submitted everything we need to build and run your submission, but not any generated files. In particular, no executables, or any of the other files xcode or visual studio generate beyond the ones already checked in.
Be sure to include the details of the system you used for the assignment in your README in case we have problems.