Assignment 2: Curves & Splines
 Due Sep 28, 2017 by 11:59am
 Points 6
 Submitting a file upload
 File Types zip
Overview
In this assignment, you will learn how to implement Bezier curves and CatmullRom splines. You will be employing Javascript to render all your curves in 2D within the browser. You will still submit a zip file with your code; however, we will grade your assignment during office hours. We will have a look at your code and your results together and grade you in person; this will only take 10 minutes. We'll post information about scheduling a time to be graded later in the week. Please make sure to be on time and bring your laptop.
This assignment comes with a new Javascript basecode, which you can obtain through git. Note that this is a new repository; so you must clone the repo from scratch.
Please refer to the text of assignment 0 if you're unsure how to clone a repository. On the command line, you can achieve this using the following command:
$ git clone https://gitlab.cs.dartmouth.edu/cs77fa17/assignment2_basecode.git
For visual tools such as SourceTree the process is slightly different, but the URL will be the same.
Before you start, open firstnamelastnamereport.html
in your browser. This html file will be both your report and your submitted assignment. Check the developer console of your browser for any error messages (check the xhour slides for how to open the console).
The report contains 5 tasks which you need to implement (Undergrads are required to implement only 4). Each task has its own simple curve editing UI that allows you to add and modify control points. You can add control points by clicking anywhere in the drawing area and a control polygon is drawn between each successive control vertex. The curve functionality is encapsulated within the resources/beziercurve.js
and resources/catmullromspline.js
files. The resources/node.js
file contains code that manages the control vertex data and its drawing routine. The resources/drawutils.js
file contains utility code that allows to draw lines, circles and text easily within a canvas element. Please go through these files to get a better understanding of all the functionality that is available to you. Each task builds upon the previous task so we encourage you to proceed in a sequential order while completing the assignment.
For undergraduates, the point break down is as follows.
 Task 1  2 pts
 Task 2  1 pts
 Task 4  1 pt
 Task 5  2 pts
For graduate students, the point break down is as follows.
 Task 1  1.5 pts
 Task 2  0.5 pt
 Task 3  1.5 pts
 Task 4  0.5 pt
 Task 5  2 pts
Task 1
In this task you will implement the De Casteljau's recursive curve split algorithm for Bezier curves of degree 2 and 3. You will implement your code in the beziercurve.js
file within the resources
folder. The javascript file has the class definition representing a Bezier curve of arbitrary degree. The current code limits the maximum number of nodes to be 4 and hence can represent both quadratic and cubic Bezier curves. You should write the De Casteljau split algorithm code within the BezierCurve.deCasteljauSplit()
function that takes in an input parameter value t
. Make sure to write appropriate code for degree 2 and 3 curves (by checking the current number of nodes in the BezierCurve.nodes
array). Hint: you may find the node.lerp() function useful for the interpolation steps needed in the de Casteljau algorithm. This function should populate the nodes of the left and right child curves, and return them in the left
and right
return values.
Once you have finished implementing the split code, you can then employ it within the BezierCurve.drawTask1()
function to draw the two split curves. You can play around with the paramter value t
by using the slider present below the canvas element in Task 1 in the report html file.
Task 2
In this task, you will build upon the split routine from task 1 to draw the actual Bezier curves. You will have to add your implementation within the BezierCurve.deCasteljauDraw()
function that takes in an input argument of the maximum recursion depth
. The recursion depth determines the number of splits employed to draw the control vertices. The depth parameter is decremented with each recursion and when the recursion reaches a depth of 0, the curve can be approximated as its control polygon. You should use the BezierCurve.drawControlPolygon()
function to draw just the control polygon of the curve.
Once you've implemented this function, you can employ it within BezierCurve.drawTask2()
which would enable you to test your code within the task 2 canvas in the report file. You can play around with the recursion depth using the slider. With increasing recursion depth, the curve should more closely resemble the actual smooth curve.
Task 3 (Only Grad Students)
This task is for grad student credit only. In the previous task, you implemented a fixed depth Bezier subdivision scheme. This scheme does not consider the curvature of the curve to determine how many recursions are required to represent the curve faithfully. In case of highly curved curves, using a low subdivision depth will result in a faceted appearance due to the individual segments of the curve approximation. Moreover, some regions of a curve are flat and could be well approximated by only a few segments, while other regions may have high curvature, requiring fine subdivision to avoid faceted artifacts. A more sophisticated approach would be to adaptively decide during recursion (using some measure of local "flatness") whether further subdivision is required or whether the current control polygon approximates its portion of the curve sufficiently well. You should implement a scheme which uses either the pixel extent of the control points, or the deviation of the interior control points from the line connecting the endpoints (as discussed in lecture) as a termination criterion. To visualize the adaptive subdivision, you should include a checkbox to visualize the endpoints of the drawn subdivided curves as small circles (so we can see that the points are spaced unevenly. Implement this scheme in the BezierCurve.adapativeDeCasteljauDraw()
function.
Once you've coded up this adaptive subdivision scheme, you can test it by using the task 3 curve editor which calls the BezierCurve.drawTask3()
function from the draw()
function in the main page.
Task 4
In this task, you will start adding functionality for drawing CatmullRom splines. You will be writing all your code within the catmullromsplines.js
file. The file contains starter code that allows you to store an arbitrary number of control points. The nodes are stored within the CatmullRomSpline.nodes
array. The provided base code already draws linear line segments between control points chosen within the canvas area. In this task, you need to compute the tangents at each control vertex (computed by looking at the next and previous control vertices) within the list of control vertices. You should implement this functionality within CatmullRomSpline.drawTangents()
.
Once you've implemented the tangent computation code, you can test it within the curve editor in the Task 4 section in the report page. The CatmullRomSpline.drawTangents()
is automatically called within the CatmullRomSpline.drawTask4()
that is called by the draw()
function in the main page. The following figure shows the tangents that are drawn at the control vertices. Note that tangents are not available at the first and the last control vertices (since computing tangents requires a previous and next vertex which are not available at these vertices).
Task 5
Once you have implemented the tangent computation task, you can implement the actual spline drawing code within the CatmullRomSpline.draw()
. You can evaluate the curve locations using the De Casteljau's recursive draw routine that you've coded earlier (using the tangents computed in the previous step) or you can explicitly evaluate the curve at fixed parameter intervals to draw the curve. Once you've implemented the draw()
routine, you can test the functionality in the task 5 curve editor area. The CatmullRomSpline.draw()
function is automatically called within the CatmullRomSpline.drawTask5()
function that is inturn called within the draw()
function in the main page. The provided report page has a slider for controlling the CatmullRomSpline.numSegments
value. You can use that value to compute the number of segments that you use to split the parametric interval equally. If you choose to draw the spline using the de Casteljau algorithm, you will have to modify the code appropriately to add a separate field to the CatmullRomSpline
class (For example, add a field called depth
) and then write appropriate code that modifies this value when the slider value is changed. This procedure is a very minor operation and can be easily implemented. The following image shows the curve being drawn along with the control polygon and tangents at every control vertex.
You will notice that the UI contains a 'tension' slider. This slider controls the CatmullRomSpline.tension
value. If you are an undergraduate student, you can safely ignore this value and implement the general spline drawing code. In case you are a grad student, you will have to implement the spline drawing function that takes this tension
parameter into account. The tension
parameter controls how sharply the curve bends at the interpolated control points. You can refer to section 15.5.3 in the textbook for more details.
What to submit
You should submit a zip file containing the entire folder for this assignment (including all js files, html files and the resources
folder). Rename firstnamelastnamereport.html
to contain your name. Fill in the report with any problems encountered and comments about the assignment.
Note that we will grade the assignments in person. You will still need to come to office hours for grading. However, you should also submit the zip file so we know you completed your assignment on time, and that you didn't copy source code from others.
Rubric
Criteria  Ratings  Pts  

Task 1
threshold:
pts


pts



Task 2
threshold:
pts


pts



Task 3
threshold:
pts


pts



Task 4
threshold:
pts


pts



Task 5
threshold:
pts


pts



Deductions
threshold:
pts


pts



Total Points:
7.5
out of 7.5
