|
Notes for Thursday April 9 class -- Making shapes with splines, part 2
What we covered in this lecture
We first showed how to create more interesting
surface of revolusion shapes using the
uvToLathe
function.
Then we implemented various techniques
required to be able to extrude
a profile shape through a spline path,
in order to create more general shapes.
The last example we implemented was
a gold ring, made by extruding
ring profile (created with a Bezier spline)
along a circular path.
I won't include lots of code in these notes,
because all of the code we created in class
is included below with the homework.
Creating a brass tack
We created a Bezier spline profile that is pointy at z = -1,
then forms a narrow tube, and then finaly flairs out wide very near z = 1.
We then used
uvToLathe
to turn this into the shape of a brass tack.
We created a brass material for it, which is basically yellow-orange metal.
The code for this is in
index.html .
|
|
|
Extruding a profile along a path
The remainder of these notes will be spent describing the
challenging problem of properly extruding a profile curve
along a 3D path, to create an extruded shape.
We implemented this in class, and created an example.
The Hairy Ball Theorem
The simplest way to create an extrusion would be to
use the heading direction W at each point along the path
to create cross vectors U and V,
which can then be used as a plane to draw the point along the profile
as vertices.
Unfortunately, there is no way to do this consistently,
without at some point creating a pinch point, where
either U or V collapses to zero length.
The reason is due to the
Hairy Ball Theorem,
which was first stated by Poincaré in the 19th century,
and finally proven by Luitzen Egbertus Jan Brouwer in 1912.
Essentially, if you try to comb down hairs all over a sphere,
at some place you end up having a cowlick -- a place
where the hairs cannot line up parallel to one another.
This applies to our situation as follows:
if you are travelling along an arbitrary
path in 3D, you can think of the direction along the path
as a point on a sphere.
You can then think of the direction of your desired cross vector
as one of those hairs you are trying to comb down.
There is no arrangement of cross vectors that will
work for every situation.
Sooner or later, the path will turn in a way that
you hit one of those cowlicks.
Adding a cross vector to a sampled path
We get around the Hairy Ball problem
by moving along the path from start to finish,
building cross vectors as we go,
making sure that each cross vector is consistent with the one before.
We wrote the code to implement this in class.
It is in
lib6.js ,
within function
sampleBezierPath() .
Shape images
The logic to create an extrusion shape is complex enough,
without needing to worry about also converting the result into a
triangle mesh.
So make things easier, we split the problem into two parts:
- Create the result of the extrusion as a shape image.
-
Convert the resulting shape image
into a triangle mesh.
A
shape image
is simple an image, with
n
rows and
m
columns,
in which every pixel
is a set of (x,y,z) coordinates.
We describe it as a three dimensional array.
For example, given a shape image
si ,
the x coordinate of column
i
in row
j
is:
si[j][i][0] .
Extruding a profile along a path, to create a shape image
The key to extruding a profile along a sampled path
is to obtain, at every step along the path,
a pair of mutually orthogonal cross vectors (U,V)
that can serve as a coordinate system in which to draw out the profile
at that point along the path.
If W is the direction of the path at that point,
the U,V,W form the three directions of a mutually orthogonal coordinate system,
with the point P along the path as the origin.
Essentially, we need to transform each point (x,y,0) of the profile by matrix multiplication:
Ux Vx Wx Px x
Uy Vy Wy Py y
Uz Vz Wz Pz 0
0 0 0 1 1
We implemented this in class within
lib6.js ,
in the function
extrudeToShapeImag() .
The key, as you can see in that implementation, is to keep using
the U from the previous step along the path,
with the new W at the next step along the path,
to compute a new V via cross product,
then use a second cross product to compute the new U.
Converting a shape image to a triangle mesh
The only tricky thing about converting a shape image to a triangle mesh
is that we need to compute the surface normal at each vertex.
We do this by first computing two tangent vectors: du and dv.
We get du by subtracting the location of the vertex at the previous
column from the vertex at the next column:
du = Vi+1,j - Vi-1,j
We get dv by subtracting the location of the vertex at the previous
row from the vertex at the next row:
dv = Vi,j+1 - Vi,j-1
We also need to deal with end cases.
If the shapes wraps around (eg: in the case of a cylinder),
then we need to use a vertex on the other side of the
mesh for the subtraction.
We implemented this in class
within
lib6.js ,
as function
shapeImageToTriangleMesh() .
Because it is so useful to extrude a profile along a path,
we added a function
extrude()
within
lib6.js
to combine the two steps of the process into one:
let extrude = (profile, path) => shapeImageToTriangleMesh( extrudeToShapeImage(profile, path) );
Creating a gold ring
Finally, we implemented a ring
by implementing function
createRingShape()
within
index.html ,
just like the ring that I wear on my finger.
First we implemented
function
createCircularPath(n)
that samples points (together with cross vectors) along a circular path.
Then we created a Bezier spline in the
shape of a cross section of the ring:
rounded on the outside, and flat on the inside
where the ring touches the finger.
That code is all found toward the end of
index.html .
|
|
|
Homework 7, due before start of class on Thursday April 16
The code that we ended up with at the end of class is in
hw7.zip.
Starting with that code, create your own original scene
that makes use of splines.
You have lots of flexibility in this assignment,
but two things are essential:
- You need to use a spline to create a 3D shape;
- You need to use a spline to create movement over time.
There are lots of opportunities for extra credit here.
For example, you can use Hermite splines
rather than Bezier splines.
If you are really ambitious, you might want to
create animated people or creatures, using spline based surfaces
of revolution for the different body parts.
This is an assignment you can really have fun with,
because you now have the tools you need both
to create really interesting shapes and
really interesting animation paths of
translation and/or rotation over time.
| |