Как нарисовать нижнюю половину круга на холсте

Я пытаюсь нарисовать нижнюю половину круга, используя соответствующие функции x=cos(theta), y=sin(theta). Если я повторяю тета от Math.PI до 2*Math.PI, вместо этого я получаю верхнюю половину круга:

введите здесь описание изображения

Что я делаю неправильно в этом фрагменте кода:

    window.onload = function() 
    {
        var canvas = document.getElementById('circle-canvas');

        if (canvas && canvas.getContext) {
            var context = canvas.getContext('2d');
            if (context) {
                context.strokeStyle = "#369";
                context.lineWidth = 4;


                j = canvas.width / 2;
                k = canvas.height / 2;
                r = canvas.width / 4; 

                function computeX(theta, r, j, k){ return r * Math.cos(theta) + j; }
                function computeY(theta, r, j, k){ return r * Math.sin(theta) + k; }

                start = Math.PI;
                context.lineTo(computeX(start, r, j, k), computeY(start, r, j, k));
                for(var theta = start; theta <= (2*Math.PI); theta += .1) 
                {
                    x = computeX(theta, r, j, k);
                    y = computeY(theta, r, j, k),

                    context.lineTo(x, y);
                }
                context.stroke();
                context.closePath();
            }
        }
    }

РЕДАКТИРОВАТЬ: я знаю о функции дуги. Мне нужно реализовать дугу таким образом, потому что это будет использоваться как часть более крупной задачи, где мне нужно вычислить каждую отдельную точку дуги.


person TheOne    schedule 29.11.2011    source источник
comment
Почему вы ожидаете получить нижний полукруг? Сравните обычно используемую систему координат и систему, используемую на холсте (увеличивается ли координата y вверх или вниз?)   -  person Roger Lindsjö    schedule 29.11.2011


Ответы (5)


Просто поставьте - перед r

y = computeY(theta, -r, j, k),

Проверено и работает

person asar    schedule 29.11.2011
comment
Это работает, но знаете ли вы, почему это работает? Больше похоже на взлом. - person TheOne; 29.11.2011
comment
это ставит мировое положение в отрицательное. - person asar; 29.11.2011
comment
@Ramin На холсте 0,0 — это верхний левый угол. Вы исходили из правого нижнего угла. Это исправляет. - person Alex Turpin; 01.12.2011

Есть функция arc.

var canvas = document.getElementById("circle-canvas");
var context = canvas.getContext("2d");

var centerX = canvas.width / 2; 
var centerY = canvas.height / 4; 

var radius = canvas.width / 4; 

// I think these values are the angles for the bottom half - otherwise use other values
var startingAngle = Math.PI;
var endingAngle = 0;
var counterclockwise = true;

context.arc(centerX, centerY, radius, startingAngle,
    endingAngle, counterclockwise);

context.lineWidth = 4;
context.strokeStyle = "#369";
context.stroke();
person Smamatti    schedule 29.11.2011

Вам нужно изменить начало на 0, а конечную точку на Math.Pi

Не совсем уверен, почему, но кажется, что холст движется по часовой стрелке, а не против часовой стрелки.

См. пример здесь: http://jsfiddle.net/kvAzb/1/

Решение выше работает, но это не правильное решение. Новое решение ниже:

ИЗМЕНИТЬ

Ага, комментарий Роджера объясняет это. Координаты холста начинаются с 0,0 как верхний левый угол, а не нижний левый угол. Поэтому вам нужно перевернуть вашу функцию computeY.

function computeY(theta, r, j, k){ return r * Math.sin(theta) + k; }

изменения к

function computeY(theta, r, j, k){ return canvas.height - (r * Math.sin(theta) + k); }

person Nico Burns    schedule 29.11.2011
comment
Забыл об этой причуде. Спасибо. :) - person TheOne; 29.11.2011

Для вас есть функция arc.

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.arc(256, 128, 128, Math.PI, 0, true);
context.stroke();

http://jsfiddle.net/9mAq5/

person Alex Turpin    schedule 29.11.2011

быстрая догадка, попробуйте изменить знак (если вы используете положительные относительные координаты, попробуйте использовать отрицательные)

person ShadowFlame    schedule 29.11.2011