2

私はRaphaelJSを使用して、次のコードを使用して、紙のランダムな位置に一連の図形を描画しています。

http://jsbin.com/ixiqiy/2/edit

私が今やろうとしているのは、グループ全体の周りに境界線を引くことができるように、最も外側の位置のセットを見つけることです。例えば:

ここに画像の説明を入力してください

誰か助けてもらえますか?ありがとう。

4

1 に答える 1

2

さて、 Jarvis MarchアルゴリズムとこのPython実装を使用して、私は自分のJS/RaphaelJSソリューションをまとめることができました。これはhttp://jsbin.com/ixiqiy/12/editにあります。

それが消えた場合に備えて、コードは次のとおりです。

(function() {

    function cmp(x, y) {  
        if (x > y) {
            return 1;
        } else if (x < y) {
            return -1;
        } else {
            return 0;
        }
    } 
    function turn(p, q, r) {
        return cmp((q[0] - p[0]) * (r[1] - p[1]) - (r[0] - p[0]) * (q[1] - p[1]), 0);
    }
    function dist(p, q) {
        var dx = q[0] - p[0];
        var dy = q[1] - p[1];
        return dx * dx + dy * dy;
    }
    function next_hull_pt(points, p) {
        var q = p,
            r,
            t;
        for (var i = 0; i < points.length; i++) {
            r = points[i];
            t = turn(p, q, r);
            if (t == -1 || t == 0 && dist(p, r) > dist(p, q)) {
                q = r;
            }
        }
        return q;
    }
    function convex_hull(points) {
        var left,
            point;
        for (var i = 0; i < points.length; i++) {
            point = points[i];
            if (!left || point[0] < left[0]) {
                left = point;
            }
        }
        var hull = [left],
            p,
            q;
        for (var i = 0; i < hull.length; i++) {
            p = hull[i];
            q = next_hull_pt(points, p);
            if (q[0] != hull[0][0] || q[1] != hull[0][1]) {
                hull.push(q);
            }
        }
        hull.push(left);
        return hull;
    }

    var paper   = Raphael(0, 0, 800, 800),
        set     = paper.set(),
        points  = [],
        point;

    for (var i = 0; i < 20; i++) {
        points[i] = [
            Math.round(Math.random() * 500) + 100,
            Math.round(Math.random() * 500) + 100
        ];
    }

    for (var i = 0; i < points.length; i++) {
        point = points[i];
        set.push(paper.circle(point[0], point[1], 5));
    }

    set.attr('fill', '#ff0000');
    set.attr('stroke', '#ffffff'); 

    var outline     = convex_hull(points),
        previous    = [0, 0],
        path        = 'M';
    for (var i = 0; i < outline.length; i++) {
        point = outline[i];
        path = path + (i == 0 ? 'M' : 'L') + point[0] + ',' + point[1] + ' ';
    }

    var path = paper.path(path);
    path.attr('stroke', '#0000ff'); 

})();
于 2012-12-11T21:27:15.913 に答える