How to Calculate Center pixels(x,y) of each small square drwan within a rectangle in HTML5 canvas - html

I have written a code that will create a rectangle and by providing values it will generate rows and columns in that rectangle,basically it is creating small squares within that rectangle.
Code can be seen here http://jsfiddle.net/simerpreet/ndGE5/1/
<h1>Example</h1>
<canvas id="t_canvas" style="border:1px solid #000000;" width="300" height="225"></canvas>
<br/>
<button id="draw">Draw</button>
<Script>
var x=50;
var y=50;
var w = 150; //width
var h = 100; //height
var columns=3;
var rows =3;
var vnp =w/columns; //vertical next point
var hnp=h/rows; //horizontal next point
var canvas = document.getElementById("t_canvas");
var ctx = canvas.getContext("2d");
$(document).ready(function() {
$('#draw').click(function() {
drawVerticalLines(parseFloat(vnp));
drawHorizontalLines(parseFloat(hnp));
ctx.fillStyle = "#FF0000";
ctx.strokeRect(x, y, w, h);
ctx.stroke();
});
});
function drawVerticalLines(np){
var np = x + np //start point of first column
while(np < w+x){
ctx.moveTo(np, y);
ctx.lineTo(np, y+h);
np = vnp + np;
}
}
function drawHorizontalLines(np){
var np = y + np //start point of first column
while(np < h+y){
ctx.moveTo(x, np);
ctx.lineTo(x+w, np);
np = hnp + np;
}
}
<script>
I have given the value of rows =3 and columns =3, so it will create a tic tac toe like squares.My requirement is when i click in a any small square at any postion,it should give me the exact center location of that particular square, iam kind of stuck here,is there any kind of algorithm which can do this?
Thanks,
Simer

The correct way to get the center point can be manifested in various ways but in essence this is what you need to do:
var mousePos = getMousePos(canvas, evt), // get adjusted mouse position
gw = vnp * 0.5, // get center of one cell
gh = hnp * 0.5,
ix = ((mousePos.x - x) / vnp)|0, // get cell index clicked
iy = ((mousePos.y - y) / hnp)|0,
cx = ix * vnp + x + gw, // scale up to get pixel position
cy = iy * hnp + y + gh;
Modified fiddle here
A quick breakdown of the following lines (showing only for x, same is for y):
ix = ((mousePos.x - x) / vnp)|0
cx = ix * vnp + x + gw
Adjust for grid by subtracting the grid's start point from the mouse position. This gives you the position within the grid:
mousePos.x - x
Quantize the value to get an index by using a single cell's width. The |0 cuts off the fractional value so we end up with an integer value which we need for the next step:
((mousePos.x - x) / vnp)|0
Now that we have an integer index [0, 2] (you need to do boundary checks or index range check for the grid) we simply multiply it with a cell width to get a pixel position for the start of a grid cell:
cx = ix * vnp
And finally add back the grid start position of the grid to get to the cell's on-screen corner as well as adding half a cell size to get center of this cell:
cx = ix * vnp + gw
A bonus is that you now have indexes (ix and iy) you can use with an array to more easy check game status.

Related

Gradient Stroke Along Curve in Canvas

I'm trying to draw a curve in canvas with a linear gradient stoke style along the curve, as in this image. On that page there is a linked svg file that gives instructions on how to accomplish the effect in svg. Maybe a similar method would be possible in canvas?
A Demo: http://jsfiddle.net/m1erickson/4fX5D/
It's fairly easy to create a gradient that changes along the path:
It's more difficult to create a gradient that changes across the path:
To create a gradient across the path you draw many gradient lines tangent to the path:
If you draw enough tangent lines then the eye sees the curve as a gradient across the path.
Note: Jaggies can occur on the outsides of the path-gradient. That's because the gradient is really made up of hundreds of tangent lines. But you can smooth out the jaggies by drawing a line on either side of the gradient using the appropriate colors (here the anti-jaggy lines are red on the top side and purple on the bottom side).
Here are the steps to creating a gradient across the path:
Plot hundreds of points along the path.
Calculate the angle of the path at those points.
At each point, create a linear gradient and draw a gradient stroked line across the tangent of that point. Yes, you will have to create a new gradient for each point because the linear gradient must match the angle of the line tangent to that point.
To reduce the jaggy effect caused by drawing many individual lines, you can draw a smooth path along the top and bottom side of the gradient path to overwrite the jaggies.
Here is annotated code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// variables defining a cubic bezier curve
var PI2=Math.PI*2;
var s={x:20,y:30};
var c1={x:200,y:40};
var c2={x:40,y:200};
var e={x:270,y:220};
// an array of points plotted along the bezier curve
var points=[];
// we use PI often so put it in a variable
var PI=Math.PI;
// plot 400 points along the curve
// and also calculate the angle of the curve at that point
for(var t=0;t<=100;t+=0.25){
var T=t/100;
// plot a point on the curve
var pos=getCubicBezierXYatT(s,c1,c2,e,T);
// calculate the tangent angle of the curve at that point
var tx = bezierTangent(s.x,c1.x,c2.x,e.x,T);
var ty = bezierTangent(s.y,c1.y,c2.y,e.y,T);
var a = Math.atan2(ty, tx)-PI/2;
// save the x/y position of the point and the tangent angle
// in the points array
points.push({
x:pos.x,
y:pos.y,
angle:a
});
}
// Note: increase the lineWidth if
// the gradient has noticable gaps
ctx.lineWidth=2;
// draw a gradient-stroked line tangent to each point on the curve
for(var i=0;i<points.length;i++){
// calc the topside and bottomside points of the tangent line
var offX1=points[i].x+20*Math.cos(points[i].angle);
var offY1=points[i].y+20*Math.sin(points[i].angle);
var offX2=points[i].x+20*Math.cos(points[i].angle-PI);
var offY2=points[i].y+20*Math.sin(points[i].angle-PI);
// create a gradient stretching between
// the calculated top & bottom points
var gradient=ctx.createLinearGradient(offX1,offY1,offX2,offY2);
gradient.addColorStop(0.00, 'red');
gradient.addColorStop(1/6, 'orange');
gradient.addColorStop(2/6, 'yellow');
gradient.addColorStop(3/6, 'green')
gradient.addColorStop(4/6, 'aqua');
gradient.addColorStop(5/6, 'blue');
gradient.addColorStop(1.00, 'purple');
// draw the gradient-stroked line at this point
ctx.strokeStyle=gradient;
ctx.beginPath();
ctx.moveTo(offX1,offY1);
ctx.lineTo(offX2,offY2);
ctx.stroke();
}
// draw a top stroke to cover jaggies
// on the top of the gradient curve
var offX1=points[0].x+20*Math.cos(points[0].angle);
var offY1=points[0].y+20*Math.sin(points[0].angle);
ctx.strokeStyle="red";
// Note: increase the lineWidth if this outside of the
// gradient still has jaggies
ctx.lineWidth=1.5;
ctx.beginPath();
ctx.moveTo(offX1,offY1);
for(var i=1;i<points.length;i++){
var offX1=points[i].x+20*Math.cos(points[i].angle);
var offY1=points[i].y+20*Math.sin(points[i].angle);
ctx.lineTo(offX1,offY1);
}
ctx.stroke();
// draw a bottom stroke to cover jaggies
// on the bottom of the gradient
var offX2=points[0].x+20*Math.cos(points[0].angle+PI);
var offY2=points[0].y+20*Math.sin(points[0].angle+PI);
ctx.strokeStyle="purple";
// Note: increase the lineWidth if this outside of the
// gradient still has jaggies
ctx.lineWidth=1.5;
ctx.beginPath();
ctx.moveTo(offX2,offY2);
for(var i=0;i<points.length;i++){
var offX2=points[i].x+20*Math.cos(points[i].angle+PI);
var offY2=points[i].y+20*Math.sin(points[i].angle+PI);
ctx.lineTo(offX2,offY2);
}
ctx.stroke();
//////////////////////////////////////////
// helper functions
//////////////////////////////////////////
// calculate one XY point along Cubic Bezier at interval T
// (where T==0.00 at the start of the curve and T==1.00 at the end)
function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
// cubic helper formula at T distance
function CubicN(T, a,b,c,d) {
var t2 = T * T;
var t3 = t2 * T;
return a + (-a * 3 + T * (3 * a - a * T)) * T
+ (3 * b + T * (-6 * b + b * 3 * T)) * T
+ (c * 3 - c * 3 * T) * t2
+ d * t3;
}
// calculate the tangent angle at interval T on the curve
function bezierTangent(a, b, c, d, t) {
return (3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b));
};
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
I am working on doing something very similar, and I just wanted to add a couple things. markE's answer is great, but what he calls tangent lines to the curve, are actually lines normal or perpendicular to the curve. (Tangent lines are parallel, normal lines are perpendicular)
For my particular application, I am using a gradient across a line with transparency. In this case, it is important to get near pixel perfect gradient regions, as overlapping transparency will get drawn twice, changing the desired color. So instead of drawing a bunch of lines perpendicular to the curve, I divided the curve up into quadrilaterals and applied a linear gradient to each. Additionally, using these quadrilateral regions reduces the number of calls to draw you have to make, which can make it more efficient. You don't need a ton of regions to get a pretty smooth effect, and the fewer regions you use, the faster it will be able to render.
I adapted markE's code, so credit to him for that great answer. Here is the fiddle: https://jsfiddle.net/hvyt58dz/
Here is the adapted code I used:
// canvas related variables
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// variables defining a cubic bezier curve
var PI2 = Math.PI * 2;
var s = {
x: 20,
y: 30
};
var c1 = {
x: 200,
y: 40
};
var c2 = {
x: 40,
y: 200
};
var e = {
x: 270,
y: 220
};
// an array of points plotted along the bezier curve
var points = [];
// we use PI often so put it in a variable
var PI = Math.PI;
// plot 400 points along the curve
// and also calculate the angle of the curve at that point
var step_size = 100/18;
for (var t = 0; t <= 100 + 0.1; t += step_size) {
var T = t / 100;
// plot a point on the curve
var pos = getCubicBezierXYatT(s, c1, c2, e, T);
// calculate the tangent angle of the curve at that point
var tx = bezierTangent(s.x, c1.x, c2.x, e.x, T);
var ty = bezierTangent(s.y, c1.y, c2.y, e.y, T);
var a = Math.atan2(ty, tx) - PI / 2;
// save the x/y position of the point and the tangent angle
// in the points array
points.push({
x: pos.x,
y: pos.y,
angle: a
});
}
// Note: increase the lineWidth if
// the gradient has noticable gaps
ctx.lineWidth = 2;
var overlap = 0.2;
var outside_color = 'rgba(255,0,0,0.0)';
var inside_color = 'rgba(255,0,0,0.7)';
// draw a gradient-stroked line tangent to each point on the curve
var line_width = 40;
var half_width = line_width/2;
for (var i = 0; i < points.length - 1; i++) {
var x1 = points[i].x, y1 = points[i].y;
var x2 = points[i+1].x, y2 = points[i+1].y;
var angle1 = points[i].angle, angle2 = points[i+1].angle;
var midangle = (angle1 + angle2)/ 2;
// calc the topside and bottomside points of the tangent line
var gradientOffsetX1 = x1 + half_width * Math.cos(midangle);
var gradientOffsetY1 = y1 + half_width * Math.sin(midangle);
var gradientOffsetX2 = x1 + half_width * Math.cos(midangle - PI);
var gradientOffsetY2 = y1 + half_width * Math.sin(midangle - PI);
var offX1 = x1 + half_width * Math.cos(angle1);
var offY1 = y1 + half_width * Math.sin(angle1);
var offX2 = x1 + half_width * Math.cos(angle1 - PI);
var offY2 = y1 + half_width * Math.sin(angle1 - PI);
var offX3 = x2 + half_width * Math.cos(angle2)
- overlap * Math.cos(angle2-PI/2);
var offY3 = y2 + half_width * Math.sin(angle2)
- overlap * Math.sin(angle2-PI/2);
var offX4 = x2 + half_width * Math.cos(angle2 - PI)
+ overlap * Math.cos(angle2-3*PI/2);
var offY4 = y2 + half_width * Math.sin(angle2 - PI)
+ overlap * Math.sin(angle2-3*PI/2);
// create a gradient stretching between
// the calculated top & bottom points
var gradient = ctx.createLinearGradient(gradientOffsetX1, gradientOffsetY1, gradientOffsetX2, gradientOffsetY2);
gradient.addColorStop(0.0, outside_color);
gradient.addColorStop(0.25, inside_color);
gradient.addColorStop(0.75, inside_color);
gradient.addColorStop(1.0, outside_color);
//gradient.addColorStop(1 / 6, 'orange');
//gradient.addColorStop(2 / 6, 'yellow');
//gradient.addColorStop(3 / 6, 'green')
//gradient.addColorStop(4 / 6, 'aqua');
//gradient.addColorStop(5 / 6, 'blue');
//gradient.addColorStop(1.00, 'purple');
// line cap
if(i == 0){
var x = x1 - overlap * Math.cos(angle1-PI/2);
var y = y1 - overlap * Math.sin(angle1-PI/2);
var cap_gradient = ctx.createRadialGradient(x, y, 0, x, y, half_width);
ctx.beginPath();
ctx.arc(x, y, half_width, angle1 - PI, angle1);
cap_gradient.addColorStop(0.5, inside_color);
cap_gradient.addColorStop(1.0, outside_color);
ctx.fillStyle = cap_gradient;
ctx.fill();
}
if(i == points.length - 2){
var x = x2 + overlap * Math.cos(angle2-PI/2);
var y = y2 + overlap * Math.sin(angle2-PI/2);
var cap_gradient = ctx.createRadialGradient(x, y, 0, x, y, half_width);
ctx.beginPath();
ctx.arc(x, y, half_width, angle2, angle2 + PI);
cap_gradient.addColorStop(0.5, inside_color);
cap_gradient.addColorStop(1.0, outside_color);
ctx.fillStyle = cap_gradient;
ctx.fill();
console.log(x,y);
}
// draw the gradient-stroked line at this point
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.moveTo(offX1, offY1);
ctx.lineTo(offX2, offY2);
ctx.lineTo(offX4, offY4);
ctx.lineTo(offX3, offY3);
ctx.fill();
}
//////////////////////////////////////////
// helper functions
//////////////////////////////////////////
// calculate one XY point along Cubic Bezier at interval T
// (where T==0.00 at the start of the curve and T==1.00 at the end)
function getCubicBezierXYatT(startPt, controlPt1, controlPt2, endPt, T) {
var x = CubicN(T, startPt.x, controlPt1.x, controlPt2.x, endPt.x);
var y = CubicN(T, startPt.y, controlPt1.y, controlPt2.y, endPt.y);
return ({
x: x,
y: y
});
}
// cubic helper formula at T distance
function CubicN(T, a, b, c, d) {
var t2 = T * T;
var t3 = t2 * T;
return a + (-a * 3 + T * (3 * a - a * T)) * T + (3 * b + T * (-6 * b + b * 3 * T)) * T + (c * 3 - c * 3 * T) * t2 + d * t3;
}
// calculate the tangent angle at interval T on the curve
function bezierTangent(a, b, c, d, t) {
return (3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b));
};

Why does Canvas's putImageData not work when I specify target location?

In trying to find documentation for Canvas context's putImageData() method, I've found things like this:
context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
(from http://www.w3schools.com/tags/canvas_putimagedata.asp)
According to the documentation I've read, x and y are an index into the source image, whereas dirtyX and dirtyY specify coordinates in the target canvas where to draw the image. Yet, as you'll see from the example below (and JSFiddle) a call to putImageData(imgData,x,y) works while putImageData(imgData, 0, 0, locX, locY) doesn't. I'm not sure why.
EDIT:
I guess my real question is why the top row of the image is black, and there are only 7 rows, not 8. The images should start at the top-left of the Canvas. They DO start at the left (and have 8 columns). Why do they not start at the top?
Answer: that's due to divide by 0 on this line when yLoc is 0:
xoff = imgWidth / (yLoc/3);
The JSFiddle:
http://jsfiddle.net/WZynM/
Code:
<html>
<head>
<title>Canvas tutorial</title>
<script type="text/javascript">
var canvas;
var context; // The canvas's 2d context
function setupCanvas()
{
canvas = document.getElementById('myCanvas');
if (canvas.getContext)
{
context = canvas.getContext('2d');
context.fillStyle = "black"; // this is default anyway
context.fillRect(0, 0, canvas.width, canvas.height);
}
}
function init()
{
loadImages();
startGating();
}
var images = new Array();
var gatingTimer;
var curIndex, imgWidth=0, imgHeight;
// Load images
function loadImages()
{
for (n = 1; n <= 16; n++)
{
images[n] = new Image();
images[n].src = "qxsImages/frame" + n + ".png";
// document.body.appendChild(images[n]);
console.log("width = " + images[n].width + ", height = " + images[n].height);
}
curIndex = 1;
imgWidth = images[1].width;
imgHeight = images[1].height;
}
function redrawImages()
{
if (imgWidth == 0)
return;
curIndex++;
if (curIndex > 16)
curIndex = 1;
// To do later: use images[1].width and .height to layout based on image size
for (var x=0; x<8; x++)
{
for (var y=0; y<8; y++)
{
//if (x != 1)
// context.drawImage(images[curIndex], x*150, y*100);
// context.drawImage(images[curIndex], x*150, y*100, imgWidth/2, imgHeight/2); // scale
// else
self.drawCustomImage(x*150, y*100);
}
}
}
function drawCustomImage(xLoc, yLoc)
{
// create a new pixel array
imageData = context.createImageData(imgWidth, imgHeight);
pos = 0; // index position into imagedata array
xoff = imgWidth / (yLoc/3); // offsets to "center"
yoff = imgHeight / 3;
for (y = 0; y < imgHeight; y++)
{
for (x = 0; x < imgWidth; x++)
{
// calculate sine based on distance
x2 = x - xoff;
y2 = y - yoff;
d = Math.sqrt(x2*x2 + y2*y2);
t = Math.sin(d/6.0);
// calculate RGB values based on sine
r = t * 200;
g = 125 + t * 80;
b = 235 + t * 20;
// set red, green, blue, and alpha:
imageData.data[pos++] = Math.max(0,Math.min(255, r));
imageData.data[pos++] = Math.max(0,Math.min(255, g));
imageData.data[pos++] = Math.max(0,Math.min(255, b));
imageData.data[pos++] = 255; // opaque alpha
}
}
// copy the image data back onto the canvas
context.putImageData(imageData, xLoc, yLoc); // Works... kinda
// context.putImageData(imageData, 0, 0, xLoc, yLoc, imgWidth, imgHeight); // Doesn't work. Why?
}
function startGating()
{
gatingTimer = setInterval(redrawImages, 1000/25); // start gating
}
function stopGating()
{
clearInterval(gatingTimer);
}
</script>
<style type="text/css">
canvas { border: 1px solid black; }
</style>
</head>
<body onload="setupCanvas(); init();">
<canvas id="myCanvas" width="1200" height="800"></canvas>
</body>
</html>
http://jsfiddle.net/WZynM/
You just had your coordinates backwards.
context.putImageData(imageData, xLoc, yLoc, 0, 0, imgWidth, imgHeight);
Live Demo
xLoc, and yLoc are where you are putting it, and 0,0,imgWidth,imgHeight is the data you are putting onto the canvas.
Another example showing this.
A lot of the online docs seem a bit contradictory but for the seven param version
putImageData(img, dx, dy, dirtyX, dirtyY, dirtyRectWidth, dirtyRectHeight)
the dx, and dy are your destination, the next four params are the dirty rect parameters, basically controlling what you are drawing from the source canvas. One of the most thorough descriptions I can find was in the book HTML5 Unleashed by Simon Sarris (pg. 165).
Having been using this recently, I've discovered that Loktar above has hit upon a VERY important issue. Basically, some documentation of this method online is incorrect, a particularly dangerous example being W3Schools, to which a number of people will turn to for reference.
Their documentation states the following:
Synopsis:
context.putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
Arguments:
imgData: Specifies the ImageData object to put back onto the canvas
x : The x-coordinate, in pixels, of the upper-left corner of the ImageData object [WRONG]
y : The y-coordinate, in pixels, of the upper-left corner of the ImageData object [WRONG]
dirtyX : Optional. The horizontal (x) value, in pixels, where to place the image on the canvas [WRONG]
dirtyY : Optional. The vertical (y) value, in pixels, where to place the image on the canvas [WRONG]
dirtyWidth : Optional. The width to use to draw the image on the canvas
dirtyHeight: Optional. The height to use to draw the image on the canvas
As Loktar states above, the CORRECT synopsis is as follows:
Correct Synopsis:
context.putImageData(imgData, canvasX, canvasY, srcX ,srcY, srcWidth, srcHeight);
Arguments:
imgData: Specifies the ImageData object to put back onto the canvas (as before);
canvasX : The x coordinate of the location on the CANVAS where you are plotting your imageData;
canvasY : The y coordinate of the location on the CANVAS where you are plotting your ImageData;
srcX : Optional. The x coordinate of the top left hand corner of your ImageData;
srcY : Optional. The y coordinate of the top left hand corner of your ImageData;
srcWidth : Optional. The width of your ImageData;
srcHeight : Optional. The height of your ImageData.
Use the correct synopsis above, and you won't have the problems that have been encountered above.
I'll give a big hat tip to Loktar for finding this out initially, but I thought it apposite to provide an expanded answer in case others run into the same problem.

Querying if component is in a position X, Y

I have a set of boxes in a board of 15x15.
I have only one eventlistener that catch a Touch Event and once a user tap on the screen, I need to know what box is nearest to such coordinate (x, y) given by the Event.
What could be the better way to get it?
Thanks in advance.
Simply take the difference of x & y positions & square them. Take the minimum d of all.
dx = x1 - x2;
dy = y1 - y2;
d = dx^2 + dy^2;
The two x & y would be of the box & the current touch point (Use .localX & .localY properties).
Here is a sample code, which probably has all you need :
board.addEventListener(TouchEvent.TOUCH_TAP,function(e) {
var minVal:int = int.MAX_VALUE;
var minBox:Sprite = null;
for(var i=0; i<board.numChildren; i++) {
var box:Sprite = board.getChildAt(i);
var d:int = Math.pow(box.x-e.localX ,2) + Math.pow(box.y-e.localY,2);
if(minVal > d) {minVal = d; minBox = box; }
}
// You have the minimum value & closest box reference here
});

Incrementing points along a line

I'm calculating increments from point A (top right) to point B (bottom left) with the following code. But as we get closer to point B, my increments get further and further off the expected path. The green line in the picture is the expected path of the white dot.
public function get target():Point { return _target; }
public function set target(p:Point):void
{
_target = p;
var dist:Number = distanceTwoPoints(x, _target.x, y, _target.y); //find the linear distance
//double the steps to get more accurate calculations. 2 steps are calculated each frame
var _stepT:Number = 2 * (dist * _speed); //_speed is in frames/pixel (something like 0.2)
if (_stepT < 1) //Make sure there's at least 1 step
_stepT = 1;
_stepTotal = int(_stepT); //ultimately, we cannot have half a step
xInc = (_target.x - x) / _stepT; //calculate the xIncrement based on the number of steps (distance / time)
yInc = (_target.y - y) / _stepT;
}
private function distanceTwoPoints(x1:Number, x2:Number, y1:Number, y2:Number):Number
{
var dx:Number = x1-x2;
var dy:Number = y1-y2;
return Math.sqrt(dx * dx + dy * dy);
}
Basically, I'm out of ideas. The only thing that seems to get the white dot to follow the green line exactly is to adjust the target's position like so:
distanceTwoPoints(x, _target.x + 2, y, _target.y + 1);
//...
xInc = (_target.x + 2 - x) / _stepT;
yInc = (_target.y + 1 - y) / _stepT;
However, this throws off other parts of the simulation where there is no angle between points, like coming into point A (top right). This makes me think the distance between the two points needs to be calculated as shorter than it actually is. Any ideas?
Flash has a great function that is really handy for this. Point.interpolate(pointA, pointB, number) It returns a point between points A and B. The third input (Number) is how close to pointA or pointB the resulting point should be, from 0 to 1. You'll have to calculate its value.
What interpolate does is basically a weighted average of the two input points, the number being the weight towards one point. If the number is 0.5, you'll get a point halfway between the two input points. 1 returns PointA, 0 returns PointB.
flash.geom.Point.interpolate() for details.
For other languages, or math in general, you can do it this way, no Trig required: point1, the origin, and point2 the end point. point3 is a point between point1 and point2. loc is a ratio from point1 to point2, how far down the line to go. loc = .25 would be a quarter of the way from point1 towards point2. point3.x = point1.x * (1 - loc) + point2.x * loc and point3.y = point1.y * (1 - loc) + point2.y * loc. This will even work for values outside of 0-1, such as a point on the line connecting point1 and point2 but not between them.

HTML5 Canvas Clip or Crop Everything but an S shape

How would I clip everything in the following drawing except for the S stroke? In other words get rid of all transparent space and only keep black S shape... thanks in advance!
=== PNG RENDERED IMAGE OF CANVAS ===
image located at --> http://buildasearch.com/ant/s.png
=== ACTUAL COORDINATES OF CANVAS DRAWING ===
var x = '68,67,66,65,64,63,62,61,60,59,57,56,55,54,53,52,51,51,51,51,51,51,51,52,55,56,52,58,60,59,61,62,64,65,66,68,70,71,72,74,75,76,77,78,78,79,79,79,79,79,79,79,79,79,79,79,79,78,76,74,71,67,59,56,54,52,49,47,46,45,43,42,41,40,39';
var y = '11,11,11,11,11,12,12,12,12,12,13,14,14,15,17,18,20,21,23,24,27,30,32,32,34,34,33,34,34,34,34,35,35,35,35,35,35,36,36,37,38,38,39,40,41,42,43,44,45,47,48,49,50,51,52,53,54,55,56,57,58,59,59,59,60,60,60,60,60,60,60,60,60,60,60';
It would be easier if your x and y were of the form [6, 3, 19] instead of '6,3,19'. For the purposes of this answer, I will assume that you have it done this way as it makes the code a bit easier.
It's quite possible to calculate afterwards, but it would get messy with getting the bit that you want and then resizing the canvas. It will end up easier and faster to calculate it before-hand if you can. Something like this should work:
// Data specification
var x = [68,67,66,65,64,63,62,61,60,59,57,56,55,54,53,52,51,51,51,51,51,51,51,52,55,56,52,58,60,59,61,62,64,65,66,68,70,71,72,74,75,76,77,78,78,79,79,79,79,79,79,79,79,79,79,79,79,78,76,74,71,67,59,56,54,52,49,47,46,45,43,42,41,40,39],
y = [11,11,11,11,11,12,12,12,12,12,13,14,14,15,17,18,20,21,23,24,27,30,32,32,34,34,33,34,34,34,34,35,35,35,35,35,35,36,36,37,38,38,39,40,41,42,43,44,45,47,48,49,50,51,52,53,54,55,56,57,58,59,59,59,60,60,60,60,60,60,60,60,60,60,60];
// Work out the extreme points in both dimensions
var xs = x.slice().sort(),
ys = y.slice().sort(),
minX = xs[0],
maxX = xs[xs.length-1],
minY = ys[0],
maxY = ys[ys.length-1];
// Resize the canvas
canvas.width = maxX - minX + 1;
canvas.height = maxY - minY + 1;
// Shift the points to fit on the shrunk canvas
x.forEach(function(v, i) {
x[i] = v - minX;
});
y.forEach(function(v, i) {
y[i] = v - minY;
});