开发者

straight line between two points

On a HTML canvas I have multiple points starting from 1 to N, this is basically a connect the dots application and is activated on touchstart.

There is validation so that they can only connect the dots from 1 and go to 2 (.. n). The issue is that right now is there is no validation that the line is a straight line and开发者_运维问答 I am looking for an algorithm to do this, Here is what I have thought so far

  1. For 2 points (x1,y1) to (x2,y2) get all the coordinates by finding the slope and using the formula y = mx + b
  2. on touchmove get the x,y co-oridnates and make sure it is one of the points from the earlier step and draw a line else do not draw the line.

Is there a better way to do this or are there any different approaches that I can take ?


Edit: I originally misunderstood the question, it seems.

As far as validating the path: I think it would be easier just to have a function that determines whether a point is valid than calculating all of the values beforehand. Something like:

function getValidatorForPoints(x1, y1, x2, y2) {
    var slope = (y2 - y1) / (x2 - x1);
    return function (x, y) {
        return (y - y1) == slope * (x - x1);
    }
}

Then, given two points, you could do this:

var isValid = getValidatorForPoints(x1, y1, x2, y2);
var x = getX(), y = getY();// getX and getY get the user's new point.
if (isValid(x, y)) {
    // Draw
}

This approach also gives you some flexibility—you could always modify the function to be less precise to accommodate people who don't quite draw a straight line but are tolerably close.

Precision: As mentioned in my comment, you can change the way the function behaves to make it less exacting. I think a good way to do this is as follows:

Right now, we are using the formula (y - y1) == slope * (x - x1). This is the same as (slope * (x - x1)) - (y - y1) == 0. We can change the zero to some positive number to make it accept points "near" the valid line as so:

Math.abs((slope * (x - x1)) - (y - y1)) <= n

Here n changes how close the point has to be to the line in order to count.

I'm pretty sure this works as advertised and helps account for people's drawing the line a little crooked, but somebody should double check my math.


function drawGraphLine(x1, y1, x2, y2, color) {

    var dist = Math.ceil(Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
    var angle = Math.atan2(y2-y1, x2-x1)*180/Math.PI;
    var xshift = dist - Math.abs(x2-x1);
    var yshift = Math.abs(y1-y2)/2;

    var div = document.createElement('div');
    div.style.backgroundColor = color;
    div.style.position = 'absolute';
    div.style.left = (x1 - xshift/2) + 'px';
    div.style.top = (Math.min(y1,y2) + yshift) + 'px';
    div.style.width = dist+'px';
    div.style.height = '3px';
    div.style.WebkitTransform = 'rotate('+angle+'deg)';
    div.style.MozTransform = 'rotate('+angle+'deg)';

}

// By Tomer Almog

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜