te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Finding if a point is on a line - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Finding if a point is on a line - Stack Overflow

programmeradmin3浏览0评论

Let's say I have a line drawn as so in HTML5 Canvas:

...
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x1,y1);
ctx.closePath();
...

I want to find out if the mouse down event happened on this line, and I have code like this:

var handleMouseDown = function(e) {
  var coords = translateCoords(e.x,e.y);
  ...
  if (ctx.isPointInPath(coords.x, coords.y) {
    ...

Now, this code works fine in the case of circles & rectangles, but not for lines. I have 2 questions:

  1. My thinking is that perhaps calling closePath() on a line itself is incorrect. Question - how can I check if the mouse down event happened on this line?

  2. How can I extend this to find if the mouse down event happened near the line?

Let's say I have a line drawn as so in HTML5 Canvas:

...
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x1,y1);
ctx.closePath();
...

I want to find out if the mouse down event happened on this line, and I have code like this:

var handleMouseDown = function(e) {
  var coords = translateCoords(e.x,e.y);
  ...
  if (ctx.isPointInPath(coords.x, coords.y) {
    ...

Now, this code works fine in the case of circles & rectangles, but not for lines. I have 2 questions:

  1. My thinking is that perhaps calling closePath() on a line itself is incorrect. Question - how can I check if the mouse down event happened on this line?

  2. How can I extend this to find if the mouse down event happened near the line?

Share Improve this question edited Jan 17, 2013 at 4:07 Peter O. 32.9k14 gold badges84 silver badges97 bronze badges asked Jan 17, 2013 at 3:35 appaappa 6131 gold badge8 silver badges12 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 9

The first step is to find the normal projection of the point onto the line. This is actually quite simple: take the distance from point 1 to the target, and point 2 to the target, and call them D1 and D2 respectively. Then calculate D1+(D2-D1)/2. This is the distance to the projected point on the line from point 1.

You can now find that point, and get the distance from that point to the target. If the distance is zero, then the target is exactly on the line. If the distance is less than 5, then the target was less than 5px away, and so on.

EDIT: A picture is worth a thousand words. Here's a diagram:


(source: adamhaskell)

(In hindsight, probably should have made those circles a different colour... Also, the purple line is supposed to be perpendicular to line AB. Blame my terrible aim with the blue line!)

Here is the approach taken from Wikipedia article Distance from a point to a line (Line defined by two points)

        var Dx = x2 - x1;
        var Dy = y2 - y1;
        var d = Math.abs(Dy*x0 - Dx*y0 - x1*y2+x2*y1)/Math.sqrt(Math.pow(Dx, 2) + Math.pow(Dy, 2));

where (x0,y0) is your Point coordinates and your Line is ((x1,y1),(x2,y2)) However, this does not checks for boundaries of the line, so I had to add another check for it.

    function inBox(x0, y0, rect) {
        var x1 = Math.min(rect.startX, rect.startX + rect.w);
        var x2 = Math.max(rect.startX, rect.startX + rect.w);
        var y1 = Math.min(rect.startY, rect.startY + rect.h);
        var y2 = Math.max(rect.startY, rect.startY + rect.h);
        return (x1 <= x0 && x0 <= x2 && y1 <= y0 && y0 <= y2);
    }

Where your Line defined as rectangle. Hope this helps.

You have two options for this. Your "simple" option is to use canvas to do it -- Read the pixel data wherever the mouse is and if it's the same color as your line then the user clicked on the line. This makes a lot of assumptions, however, like that everything on your canvas is rendered in a different solid color. This is possible, however, as a mon trick is to render everything to an off-screen canvas in a different solid color. Then when the user clicks something you know exactly what it is by reading the color of that one pixel and mapping it back to the original object.

But that's not exactly what you asked for :)

You don't want to know if the user clicked on a line because they almost never will. A line is infinitely thin, so unless it's exactly horizontal or exactly vertical they will never click on it. What you want instead is to see how far the mouse is from the line. Kolink just answered that part, so I'll stop here :)

发布评论

评论列表(0)

  1. 暂无评论