CG experimentⅠ: Let's move your stick man

Experiment introduction:

Simulate a stick man and make it walk like a real man, based on C++ & openGL.

options:
s: stand
w: walk forward
b: walk back

demo:


如无法打开视频请点击链接:
http://v.youku.com/v_show/id_XMjY5MTU2MDAwMA==.html?spm=a2h3j.8428770.3416059.1



detail:

I drew the robot use square and sphere. To animate the robot, I used some function to be assigned via keyword actions. I added rotation and translation effect for the motion in animated robot.For every part of the robot, the program will calculate the co-ordinate and draw it over and over again.
First,the robot is divided into several parts:head,hip,two legs(each has two parts),two arms(each has two parts).Second,hierarchies are a vital tool for modeling and animation.I used the body as root,thus head,legs,and arms are its children.And the forearm is the child of its upper arm.Third,Control for each joint angle, plus global position and orientation,Recursive algorithm that descends model tree, doing transformations, pushing, popping, and drawing.

The Recursive algorithm:
-load the identity matrix
-for each internal node:
-push a new matrix onto the stack
-concatenate transformations onto current transformation matrix
-recursively descend tree
-pop matrix off of stack
-for each leaf node:
-draw the geometric primitive using the current transformation matrix

Relevant OpenGL routines:
-glPushMatrix(), glPopMatrix()
push and pop the stack. push leaves a copy of the current matrix on top of the stack
-glLoadIdentity(), glLoadMatrixd(M)
load the Identity matrix, or an arbitrary matrix, onto top of the stack
-glMultMatrixd(M)
multiply the matrix C on top of stack by M. C = CM
-glOrtho (x0,y0,x1,y1,z0,z1)
set up parallel projection matrix
-glRotatef(theta,x,y,z), glRotated(…)
axis/angle rotate. “f” and “d” take floats and doubles, respectively
-glTranslatef(x,y,z), glScalef(x,y,z)
translate, rotate.


Part of code:
//画右腿
glPushMatrix();
glTranslatef(moveX, 0.0, moveZ);  //平移原点(0,0,0)个距离
glRotatef(180, 0.0, 1.0, 0.0);  
glTranslatef(0.325, 0.0, 0.0); 
glRotatef(swingRight, 1.0, 0.0, 0.0);
//下调坐标系画右大腿
glTranslatef(0.0, -0.6, 0.0);
glColor3f(1.0, 1.0, 1.0);
//画右大腿
glPushMatrix();
glScalef(0.4, 1.0, 0.4);  //模型缩放,机器人的大腿是一个0.4*1*0.4的立方体
glutSolidCube(1);
glPopMatrix();

glTranslatef(0.0, -0.5, 0.0);
glRotatef(swingSmall, 1.0, 0.0, 0.0);
glTranslatef(0.0, -0.5, 0.0);
glColor3f(1.0, 1.0, 1.0);
//画右小腿
glPushMatrix();
glScalef(0.3, 1.0, 0.3);
glutSolidCube(1.0);
glPopMatrix();
glPopMatrix();

conclusion:

这次实验是画一个火柴人,能实现基本的运动和对应关节弯曲。整个机器人由头部、躯干、两个手臂(分为上臂和下臂)、两条腿(分为大腿和小腿)组成, 实验的关键在于构建一个树形结构,即“牵一发而动全身”,每个部位的对应动作和设定都 与它的父节点相关。我选择了上半部分驱赶作为根节点,在该绘制函数中递归调用画头的函数和画两条腿的函数以及画两个手臂的函数, 在画大腿的函数中调用画小腿的函数,在画上臂的函数中调用画小臂的函数。通过递归的调用身体各个部分的绘图函数,来完成stick man的绘制。 关于如何让火柴人运动起来,只要确定每一帧下火柴人的位置,不断重绘场景,那么火柴人就等于运动起来了。此处由一个时间函数times控制,不断调用绘图 函数完成场景的绘制。重复这个过程,看上去就是一个运动的火柴人。
由于借助了openG库,关节的活动和火柴人移动的实现相对比较简单,坐标系的移动由glTranslatef实现, 关节旋转效果由glRotatef函数实现,只需用控制好函数中的旋转的方向和角度即可。难点在于开始时如何构建树形层次结构,这样可以大大简化工作。通过本次实验, 我对openGL有了初步的了解,学会了使用一些函数,对图形学的坐标变换、旋转等概念也有了比较清晰的理解。

Other project