Как вы удаляете линию в arc () в рисовании на холсте Javascript? - PullRequest
2 голосов
/ 29 июня 2011

Я пытаюсь нарисовать дугу на холсте в Javascript, но я хочу избавиться от линии, которую Javascript автоматически рисует. С нарисованной линией есть две проблемы: а) fill () неисправности б) похоже на лук

Вот изображение того, что я имею и чего хочу: Arcs Слева - это то, что у меня есть в JS, справа - то, что у меня есть в Java. Реализация Java довольно неэффективна, и я хотел бы использовать уже доступные функции.

Вот соответствующие функции JS:

function pointAt(center, l, theta){
    return {
        x : Math.sin(theta) * l + center.x,
        y : Math.cos(theta) * l + center.y
    };
}

function drawArc(ctx, center, l, theta, sweep, label, thickness){
    var p0 = pointAt(center, l, theta);
    var p1 = pointAt(center, l + thickness, theta);
    var p2 = pointAt(center, l + thickness, theta + sweep);
    var p3 = pointAt(center, l, theta + sweep);
    ctx.fillStyle = "red";
    drawPoint(ctx, p0);
    ctx.fillStyle = "blue";
    drawPoint(ctx, p1);
    ctx.fillStyle = "green";
    drawPoint(ctx, p2);
    ctx.fillStyle = "yellow";
    drawPoint(ctx, p3);

    ctx.beginPath();
    ctx.moveTo(p0.x, p0.y);
    ctx.lineTo(p1.x, p1.y);
    ctx.arc(center.x, center.y, l + thickness, theta, theta + sweep, false);
    ctx.moveTo(p2.x, p2.y);
    ctx.lineTo(p3.x, p3.y);
    ctx.arc(center.x, center.y, l, theta + sweep, theta, true)
    ctx.closePath();
    ctx.fill();
    ctx.stroke();

    //TODO: draw label!!!
}

function drawPoint(ctx, p){
    ctx.fillRect(p.x - 4, p.y - 4, 8, 8);
}

Вот рабочая реализация на Java:

       private static void drawArc(Graphics g, Point center, int l, double theta, double sweep, String label, int thickness){
        for (double i = 0; i < thickness; i+=.5) { //hardcoded
            Point last = pointAt(center, l + i, theta);
            for(double t = theta; t < theta + sweep; t+=.01){
                Point cur = pointAt(center, l + i, t);
                g.drawLine(last.x, last.y, cur.x, cur.y);
                last = cur;
            }
        }
        double t = theta + sweep / 2;
        Point p = pointAt(center, l + 15, t);
        int size = g.getFontMetrics().stringWidth(label);
        BufferedImage img = new BufferedImage(size * 2, size * 2, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();
        g2.setColor(Color.RED);
        double rot = (Math.PI / 2 - t);
//      System.out.println(rot / Math.PI + "PI");
        boolean b = true;
        if(rot < -Math.PI / 2){
            rot += Math.PI;
            b = false;
        }
        g2.setTransform(AffineTransform.getRotateInstance(rot, size, size));
        g2.drawString(label, size, size);
        g2.dispose();
        if(!b)
            size *= 1.75; //magic value or hardcoded???
        g.drawImage(img, p.x - size, p.y - size, null);
    }

Итак, мой вопрос: Как превратить банан в толстую дугу?

Ответы [ 3 ]

3 голосов
/ 29 июня 2011

Просто нарисуйте внешнюю дугу по часовой стрелке, а затем внутреннюю дугу против часовой стрелки.Холст автоматически закроет концы прямыми линиями для вас.

var c = document.getElementById('c');
var ctx = c.getContext('2d');
ctx.beginPath();
ctx.arc(0,0,50,0,-Math.PI * 0.5, false);
ctx.arc(0,0,25,-Math.PI * 0.5,0, true);
ctx.fillStyle = '#0f0';
ctx.fill();
ctx.strokeStyle = '#0f0';
ctx.stroke();
ctx.closePath();

http://jsfiddle.net/tMEdq/

Кроме того, вот хорошие ссылки: http://diveintohtml5.ep.io/canvas.html#divingin http://www.nihilogic.dk/labs/canvas_sheet/HTML5_Canvas_Cheat_Sheet.png

2 голосов
/ 29 июня 2011

У вас слишком много вызовов для рисования - это все, что вам нужно:

ctx.beginPath();
ctx.arc(center.x, center.y, l + thickness, theta, theta + sweep, false);
ctx.arc(center.x, center.y, l, theta + sweep, theta, true);
ctx.closePath();
ctx.fill();
ctx.stroke();

Просто нарисуйте первую дугу, которая автоматически соединится со следующей, и затем закройте путь, чтобы завершитьloop.

У вас также есть неправильные вызовы sin и cos в pointAt() - sin() должны изменить координату оси Y, а не оси X!

Рабочая демонстрация на http://jsfiddle.net/alnitak/zChSe/

1 голос
/ 29 июня 2011

Просто сделай:

function drawArc(ctx, center, l, theta, sweep, label, thickness){
    var p0 = pointAt(center, l, theta);
    var p1 = pointAt(center, l + thickness, theta);
    var p2 = pointAt(center, l + thickness, theta + sweep);
    var p3 = pointAt(center, l, theta + sweep);
    ctx.fillStyle = "red";
    drawPoint(ctx, p0);
    ctx.fillStyle = "blue";
    drawPoint(ctx, p1);
    ctx.fillStyle = "green";
    drawPoint(ctx, p2);
    ctx.fillStyle = "yellow";
    drawPoint(ctx, p3);

    ctx.beginPath();
    //ctx.moveTo(p0.x, p0.y);
    //ctx.lineTo(p1.x, p1.y);
    ctx.arc(center.x, center.y, l + thickness, theta, theta + sweep, false);
    //ctx.moveTo(p2.x, p2.y);
    //ctx.lineTo(p3.x, p3.y);
    ctx.arc(center.x, center.y, l, theta + sweep, theta, true);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();

    //TODO: draw label!!!
}

«Боковые» линии размещены имплантатом, см. http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arc.

...