image

Bezier Cam Designer Experiment

The experiment is working. The JavaScript code allows a fixed number of points to be manipulated to create a poly-Bezier shape. The Bezier curve is drawn “by hand” for both the normal version and for the version that uses polar coordinates.

The interesting thing that I discovered is that a smooth shape in the linear version might not be quite as smooth in the polar version.

The linear version represents the cam profile which is the movement of a follower over time. It is a good way to design cams as long as that polar view is there to make any unusable shapes more obvious. (edit to say that this might not be true and that a good looking profile means a usable cam regardless of what interesting features show up when viewing the cam itself)

The experiment page for this cam be found here.

I am still working on the JavaScript code to draw the curves but here is an early version of it. I have no idea if JavaScript has optimization to temporarily save portions of an equation so I do some of the repetitive math and save the results in variables to possibly speed things up. Note that my coordinate system uses the center of the canvas as the 0,0 point. I don’t include the code to draw the cam but this is the web and it’s available by getting the entire .js file from my site.

function GetBezierPoint( point0, point1, point2, point3, position )
{
	var point = new Point( 0, 0 );
	var t = position;
	var mt = 1-t;
	var mt_mt_mt = mt*mt*mt;
	var t_t_t = t*t*t;
	var t_t_mt = t*t*mt;
	var t_mt_mt = t*mt*mt;
	
	point.x = (point0.x * mt_mt_mt) + 3 * point1.x * t_mt_mt + 3 * point2.x * t_t_mt + point3.x*t_t_t;	
	point.y = (point0.y * mt_mt_mt) + 3 * point1.y * t_mt_mt + 3 * point2.y * t_t_mt + point3.y*t_t_t;

	return point;
}

function DrawBezier( point0, point1, point2, point3, color )
{
	var distance = Distance( point0, point1 ) + Distance( point1, point2 ) + Distance( point2, point3 );
	
	var Steps = distance / 15.0; // this division seems to make the curves always look good enough.
	
	var xc = world.width / 2.0;
	var yc = world.height / 2.0;
	context.strokeStyle = color;
	context.lineWidth = 1.5;
	
	context.beginPath();
	context.moveTo( xc + point0.x, yc + point0.y );
	
	var Gap = 1.0 / Steps;
	for( var Step = Gap; Step < 1; Step += Gap )
	{
		var point = GetBezierPoint( point0, point1, point2, point3, Step );
		context.lineTo( xc + point.x, yc + point.y );
	}
	context.lineTo( xc + point3.x, yc + point3.y );
	context.stroke();
}