JavaScript
var canvas = document.getElementById('c')
, ctx = canvas.getContext('2d');
// http://www.williammalone.com/briefs/how-to-draw-ellipse-html5-canvas/
function bezierEllipse(ctx,x,y,w,h){
ctx.beginPath();
ctx.moveTo(x, y - h/2); // A1
ctx.bezierCurveTo(
x + w/2, y - h/2, // C1
x + w/2, y + h/2, // C2
x, y + h/2); // A2
ctx.bezierCurveTo(
x - w/2, y + h/2, // C3
x - w/2, y - h/2, // C4
x, y - h/2); // A1
ctx.closePath();
}
// http://stackoverflow.com/a/8372834/80582
function scaleEllipse(ctx, x, y, rx, ry){
ctx.save();
ctx.beginPath();
ctx.translate(x-rx, y-ry);
ctx.scale(rx, ry);
ctx.arc(1, 1, 1, 0, 2 * Math.PI, false);
ctx.closePath();
ctx.restore();
}
var cx = 50
, cy = 50
, rx = 50
, ry = 25;
//bezierEllipse(ctx,cx,cy,rx*2,ry*2) // w, h
//ctx.strokeStyle = 'blue'
//ctx.stroke()
scaleEllipse(ctx,cx,cy,rx,ry) // rx, ry
ctx.strokeStyle = 'red'
ctx.stroke()
ctx.fillStyle = 'red'
ctx.fillRect(cx-2,cy-2,4,4);
console.log('center',cx,cy)
var theta = Math.PI/2
, x=cx+Math.cos(theta)*rx
, y=cy+Math.sin(theta)*ry
ctx.fillStyle = 'blue'
ctx.fillRect(x-2,y-2,4,4);
console.log('position',x,y)
var theta = Math.atan2(y/cy,x/cx)
, ny = ry * Math.sin(theta)
, nx = rx * Math.cos(theta);
ctx.beginPath();
ctx.moveTo(x,y)
ctx.lineTo(x+nx,y+ny)
ctx.strokeStyle = 'blue'
ctx.stroke()
console.log('normal',nx,ny)
var r = Math.sqrt(nx*nx+ny*ny)
, ux = nx/r
, uy = ny/r;
console.log('unit normal',ux,uy)