diff --git a/hw2/.DS_Store b/hw2/.DS_Store new file mode 100644 index 00000000..7877fe42 Binary files /dev/null and b/hw2/.DS_Store differ diff --git a/hw2/images/beziercurve_6.png b/hw2/images/beziercurve_6.png new file mode 100644 index 00000000..96396c26 Binary files /dev/null and b/hw2/images/beziercurve_6.png differ diff --git a/hw2/images/beziercurve_6_curve.png b/hw2/images/beziercurve_6_curve.png new file mode 100644 index 00000000..f69cf941 Binary files /dev/null and b/hw2/images/beziercurve_6_curve.png differ diff --git a/hw2/images/beziercurve_6_step1.png b/hw2/images/beziercurve_6_step1.png new file mode 100644 index 00000000..14b70959 Binary files /dev/null and b/hw2/images/beziercurve_6_step1.png differ diff --git a/hw2/images/beziercurve_6_step2.png b/hw2/images/beziercurve_6_step2.png new file mode 100644 index 00000000..e8c8001c Binary files /dev/null and b/hw2/images/beziercurve_6_step2.png differ diff --git a/hw2/images/beziercurve_6_step3.png b/hw2/images/beziercurve_6_step3.png new file mode 100644 index 00000000..082d41ed Binary files /dev/null and b/hw2/images/beziercurve_6_step3.png differ diff --git a/hw2/images/beziercurve_6_step4.png b/hw2/images/beziercurve_6_step4.png new file mode 100644 index 00000000..7a3512d5 Binary files /dev/null and b/hw2/images/beziercurve_6_step4.png differ diff --git a/hw2/images/beziercurve_6_step5.png b/hw2/images/beziercurve_6_step5.png new file mode 100644 index 00000000..ecc32dd4 Binary files /dev/null and b/hw2/images/beziercurve_6_step5.png differ diff --git a/hw2/images/beziercurve_6_step5_curve.png b/hw2/images/beziercurve_6_step5_curve.png new file mode 100644 index 00000000..20a25800 Binary files /dev/null and b/hw2/images/beziercurve_6_step5_curve.png differ diff --git a/hw2/images/cube1.png b/hw2/images/cube1.png new file mode 100644 index 00000000..90f6be8d Binary files /dev/null and b/hw2/images/cube1.png differ diff --git a/hw2/images/cube2.png b/hw2/images/cube2.png new file mode 100644 index 00000000..5a30e4f5 Binary files /dev/null and b/hw2/images/cube2.png differ diff --git a/hw2/images/cube3.png b/hw2/images/cube3.png new file mode 100644 index 00000000..ed9cfca7 Binary files /dev/null and b/hw2/images/cube3.png differ diff --git a/hw2/images/cube4.png b/hw2/images/cube4.png new file mode 100644 index 00000000..9b1d0bda Binary files /dev/null and b/hw2/images/cube4.png differ diff --git a/hw2/images/cube5.png b/hw2/images/cube5.png new file mode 100644 index 00000000..ce6ccad0 Binary files /dev/null and b/hw2/images/cube5.png differ diff --git a/hw2/images/part1_downscroll.png b/hw2/images/part1_downscroll.png new file mode 100644 index 00000000..df3e70ff Binary files /dev/null and b/hw2/images/part1_downscroll.png differ diff --git a/hw2/images/part1_scroll.png b/hw2/images/part1_scroll.png new file mode 100644 index 00000000..2b5d81c3 Binary files /dev/null and b/hw2/images/part1_scroll.png differ diff --git a/hw2/images/part1_upscroll.png b/hw2/images/part1_upscroll.png new file mode 100644 index 00000000..920a855c Binary files /dev/null and b/hw2/images/part1_upscroll.png differ diff --git a/hw2/images/part2_teapot.png b/hw2/images/part2_teapot.png new file mode 100644 index 00000000..cd2ef782 Binary files /dev/null and b/hw2/images/part2_teapot.png differ diff --git a/hw2/images/part3_flat.png b/hw2/images/part3_flat.png new file mode 100644 index 00000000..bd603835 Binary files /dev/null and b/hw2/images/part3_flat.png differ diff --git a/hw2/images/part3_phong.png b/hw2/images/part3_phong.png new file mode 100644 index 00000000..dfbd8d77 Binary files /dev/null and b/hw2/images/part3_phong.png differ diff --git a/hw2/images/part4_beforeFilp.png b/hw2/images/part4_beforeFilp.png new file mode 100644 index 00000000..8d55b8ee Binary files /dev/null and b/hw2/images/part4_beforeFilp.png differ diff --git a/hw2/images/part4_flipped.png b/hw2/images/part4_flipped.png new file mode 100644 index 00000000..6a724f5f Binary files /dev/null and b/hw2/images/part4_flipped.png differ diff --git a/hw2/images/part5_sf.png b/hw2/images/part5_sf.png new file mode 100644 index 00000000..4d9214e4 Binary files /dev/null and b/hw2/images/part5_sf.png differ diff --git a/hw2/images/part5_splitEdge.png b/hw2/images/part5_splitEdge.png new file mode 100644 index 00000000..1a9ecc9c Binary files /dev/null and b/hw2/images/part5_splitEdge.png differ diff --git a/hw2/images/preprocess.png b/hw2/images/preprocess.png new file mode 100644 index 00000000..171513e9 Binary files /dev/null and b/hw2/images/preprocess.png differ diff --git a/hw2/index.html b/hw2/index.html index 13b78467..99a81b0e 100644 --- a/hw2/index.html +++ b/hw2/index.html @@ -1,7 +1,482 @@ - -
- - - Homework 2 index.html here - + + + + ++ This assignment implements various aspects in modifying meshes. The first section deals with Bezier curves and de Casteljau Subdivision, which are used + to model smooth curves and surfaces, first in 1D then in more dimensions. The second section is on triangle meshes and halfedge data structure, where functions on + Phong shading, edge flip and split, and loop subdivision are implemented. These functions modify meshes in order for them to appear more accurate and smoother. +
++ De Casteljau's algorithm is a recursive algorithm that splits line segments (in this case line segments between points of the Bezier curve) + with points and continues to do so with the new points generated from the previous recursive step until it converges to the single desired final point. + This desired final point is the point that lies on the Bezier curve at the parameter t. + + For Part 1, in BezierCurve::evaluateStep(...) I implemented a for loop which iterated through the parameter vector "points" which consists of + Vector2D elements that represent coordinate points. While iterating through each point in "points", a linear interpolation was calculated with + the current point and next point (i + 1). The resulting point was then added to a vector of intermediate points which is returned at the end + of the function, populated with all the intermediate points evaluated at the step of the de Cateljau's algorithm. + +
++ I created this Bezier curve with 6 control points. Control points (0.200, 0.850), (0.300, 0.400), (0.500, 0.550), (0.700, 0.850), (1.000, 0.900), (1.300, 0.200). +
+ +
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+ Bezier surfaces can also be evaluated by de Casteljau's algorithm, one must linearly interpolate first in one direction and then in the other, + in this case we do it through (u, v), and we are also working with Vector3D coordinates rather than Vector2D coordinates. In separable 1D de + Casteljau's algorithm the coordinates are first evaluated through the in u space, once all the final points are found in the u space they are + then passed in to be linearly interpolated in the v space. This then results in a surface point, thus the de Casteljau algorithm being applied + to a Bezier surface. + +
+ ++ Implementation for BezierPatch::evaluateStep(...) is very similar to Part 1, although in this case the parameter is a Vector3D not Vector2D. It + is a for loop that goes through all the points, linearly interpolates them with their next neighboring point and returns its intermediate + points. + + For BezierPatch::evaluate1D(...), I implemented a while loop that continues to interate until a single point remains (the final point). Within + the while loop BezierPatch::evaluateStep(...) is called on the "points" parameter and its result is assigned back to "points" to be passed in + at the next step (iteration of loop) until the result converges to a single coordinate point, which is then returned. + + BezierPatch::evaluate(...) deals with the u and v spaces, for this function I interated through the 2D controlPoints vector passing in the + vector at each index into evaluate1D with u as the scalar interpolation parameter. The resulting points are added to a vector of Vector3D + points, where after the for loop terminates it is passed in to evaluate1D with the v scalar interpolation parameter. This produces the + point on the surface and is returned. +
++ To compute the area-weighted avergae of normals at this vertex I intereated through all the current halfedge's neighboring triangles by its halfedges and corresponding vertices. + Since the halfedges iterate in a single direction, this prevent double counting of triangles when computing the area + weighted total. In the while loop the directional vectors of the edges are computed by subtracting the two vertices of the incident + triangle from the originating vertex. The cross product of these edge length vectors is then + divided by the magnitude of the cross product and multiplied by 1/2 to get the area of the triangle. This is then multipled to the + triangle's face's normal and added to the area-weighted total Vector3D, where then outside the loop it is divided by its magitude to + normalize the result. Finally, the function returns this result which is the approximate unit normal at this vertex. + +
+
+
+ |
+
+
+ |
+
+ To implement the flipEdge function I first drew the diagram provided of the two triangles with a shared edge and labeled every part of it according to the flipEdge rules. + From there I created various varibles to label the pointers of each part of the diagram and used them to when reassigning. I reassigned the vertices' and faces' + halfegdes first and then used setNeighbors to reassign the halfedges (its next, twin, vertex, edge, and face). Finally, I return the edge that was intially passed in but + updated now with its reassignments. + +
+
+
+ |
+
+
+ |
+
+ A bug I had trouble with was only using the setNeighbors() function to update the halfedges and forgetting to assign the vertices' and faces' halfedge attribute to its + new flipped value as well, which was causing incorrect and odd flips like disapearing faces. +
++ Following the same process as in part 4, I drew the diagram of an edge split, labeled all new elements and relabeled elements that would need to be reassigned + and used this diagram as a guide to write the function. In the function, I first declared all the variables that would represent the pointers, then created the new faces, + edges, and vertex. For the edges that were created, I also set its "isNew" attribute to true to be later used in part 6. + Then assigned the vertices', faces', and edges' corresponding halfedges. Afterwards, I assigned all of the halfegdes' new corresponding attributes after the split + with setNeighbors(). + +
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+ Intially I was adding too many new edges since I had diffculty with reassigning some of the edges that were already in the mesh and although in part 5 the + function seemed to be work correctly, these bugs presented themselves in part 6. I then figured out how to correctly reassign the edge to be split and kept all + the edges the mesh originally had and reduced the new edges I was adding down to 2 rather than 4. This fix then allowed my part 6 to work as well. +
++ For Part 6, I closely followed the workflow provided in the doc-string of the function. First, I iterated through all the vertices with a for loop and calculated its new + position with the formula provided in the spec and for retrieving all its neighboring vertices for "original_neighbor_postion_sum" part of the formula, I had a while loop inside each iteration + of the for loop. At the end of this for loop I set all the vertices to isNew = false since they are the original vertices of the mesh and assign its newPosition to the calculated + position. I then loop through all the edges of the mesh with a while loop and calculated the positions of all the new vertices with the other formula provided and set this value to + the newPosition value of the edge. Afterwards is the loop that deals with splitting the edges. Orginally I had a for loop when dealing with edges but that lead to infinite loops + since splitting the edges kept creating more therefore the increment of the for loop kept on going since it never met the edgesEnd() condition. To fix this I then implemented it through + a while loop, in the while loop I checked if both vertices of the edge were from the original mesh and if so split the edge and set the returned vertex to isNew true and its newPosition to + the edges newPosition. I also had a bug here where I just directly set the position of the new vertex and disregarded the newPosition so fixed it by setting the newPosition. I then looped through the + + edges again to flip them here I checked the conditions where if the edge was new and if one vertex was new and the other old, if so then it'd flip the edge. Finally I iterate through all the vertices again + and set it's position to the value in its newPosition. The final bug I encountered was forgetting to set the original edges in the mesh to isNew = false so I added that in a while + loop before the splitting loop and that allowed Part 6 to function properly. +
+
+
+ |
+
+
+ |
+
+ The sharp corners and edges after loop subdivision appear to become more smooth and rounded. By pre-splitting some edges before the loop subdivision does reduce this effect, the pre-split edges after loop + subdivision seem to retain a more flat shape. +
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ Pre-processing the cube with edge splits and flips does aid in the cube being subdivided more symmetrically since it helps it keep its flat sides. Since the original + mesh does not have many triangles to begin with when they are all split and flipped in a loop they tend to lose shape since loop subdivision creates a mesh with increased + equal sized triangles thus losing information and symmetry the original shape had. By splitting and flipping before loop subdivision it creates more triangles that then keep more + information of their original shape. For example, in the cube each side face is represented by two triangles, when in a loop you split + these triangles and then flip them so the cube losses its original corners since the single triangles + of the corner were split and flipped making them more rounded. With more triangles that are smaller and closer to the corner the rounded effect of splititng and + fliiping is on a much smaller scale thus + the overall mesh keeps more of its shape. +
+