Processing math: 100%

Rotation

Counter clockwise (right hand rule with thumb on arrow side) is positive.

Rotation Matrix

Qx=[1000cosαsinα0sinαcosα]Qy=[cosα0sinα010sinα0cosα]Qz=[cosαsinα0sinαcosα0001]

Important Case: Rotate axis (0,0,1) to (1,1,1)

Multiply two rotation matrices together and work out what the angles α and θ are.

Axis-angle

Rotate about axis a by angle θ.

Important Case: Rotate axis (0,0,1) to (1,1,1)

Axis of rotation = normalize(target vector × orig vector)

norm(af×a0)=norm((1,1,1)×(0,0,1))=(1,1,0)/12+(1)2+0=(1/2,1/2,0)

Angle of rotation = cos1(unit target dot unit orig)

cosθ=ˆat׈a0=1/3sinθ=1cos2(θ)=2/3

Substitute into the matrix:

Axis Angle to Rotation Matrix

Quaternions

Cross product of two vectors:

[a1a2a3]×[b1b2b3]=[a2b3a3b2a3b1a1b3a1b2a2b1]

Multiplication:

q1q2=(w1,v1)×(w2,v2)=(w1w2v1×v2,(Scalar)w1v2+w2v1+v1×v2)(Vector)

FKIK

FK

T=LrootRrootL1R1LkRk
void renderJoints(JOINT* joint, float*data, float scale) {	
	glPushMatrix();

	// translate
	if ( joint->parent == NULL ) { // is Root
		glTranslatef( data[0] * scale, data[1] * scale, data[2] * scale );
	} else {
		glTranslatef( joint->offset.x*scale, joint->offset.y*scale, joint->offset.z*scale );
	}

	// rotate
	for ( uint i=0; i<joint->channels.size(); i++ ) {
		CHANNEL *channel = joint->channels[i];
		if ( channel->type == X_ROTATION )
			glRotatef( data[channel->index], 1.0f, 0.0f, 0.0f );
		else if ( channel->type == Y_ROTATION )
			glRotatef( data[channel->index], 0.0f, 1.0f, 0.0f );
		else if ( channel->type == Z_ROTATION )
			glRotatef( data[channel->index], 0.0f, 0.0f, 1.0f );
	}

	// end site
	if ( joint->children.size() == 0 ) {
		renderSphere(joint->offset.x*scale, joint->offset.y*scale, joint->offset.z*scale,0.07);
	}
	if ( joint->children.size() == 1 ) {
		JOINT *  child = joint->children[ 0 ];
		renderSphere(child->offset.x*scale, child->offset.y*scale, child->offset.z*scale,0.07);
	}
	if ( joint->children.size() > 1 ) {
		float  center[ 3 ] = { 0.0f, 0.0f, 0.0f };
		for ( uint i=0; i<joint->children.size(); i++ )
		{
			JOINT *  child = joint->children[i];
			center[0] += child->offset.x;
			center[1] += child->offset.y;
			center[2] += child->offset.z;
		}
		center[0] /= joint->children.size() + 1;
		center[1] /= joint->children.size() + 1;
		center[2] /= joint->children.size() + 1;

		renderSphere(center[0]*scale, center[1]*scale, center[2]*scale,0.07);

		for ( uint i=0; i<joint->children.size(); i++ )
		{
			JOINT *  child = joint->children[i];
			renderSphere(child->offset.x*scale, child->offset.y*scale, child->offset.z*scale,0.07);
		}
	}

	// recursively render all joints
	for ( uint i=0; i<joint->children.size(); i++ )
	{
		renderJointsGL( joint->children[i], data, scale );
	}
	glPopMatrix();
}

Forward Kinematics

IK

a = axis of rotation

r = distance vector from joint to end effector

m = number of effectors

ve = velocity of end effector in one step

ωe = angular velocity of end effector in one step

J=[a1×r1a2×r2am×rma1a2am]

Solving: [veωe]=J[Δθ1Δθm][Δθ1Δθm]=J+[veωe]θt+1=θt+Δθ

Moore-Penrose Pseudoinverse

Or see gradient descent (Jacobian Transpose).

Particle Systems

Hooke’s Law + Damping:

Euler’s Method

vt=f(xt,t)xt+1=xt+Δtf(xt,t)

Midpoint method

xt+1/2=xt+δt2vtvt+1/2=f(xt+1/2,t+1/2)xt+1=xt+Δtvt+1/2

Mass Spring Systems

x=M1(Ex+F)

Mass Spring Systems