Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   canvas и метод arc (https://javascript.ru/forum/events/33223-canvas-i-metod-arc.html)

cyber 14.11.2012 17:34

canvas и метод arc
 
не совсем пойму как работает метод arc обьекта CanvasRenderingContext2D
как я понял исходя из статьи https://developer.mozilla.org/ru/doc...B3%D1%83%D1%80 и еще нескольких других ctx.arc(x, y , radius ,startAngle,endAngle);
<!DOCTYPE HTML>
<html>
  <head>
    <style>
      canvas {
      
        border:1px solid black;
      }
    
    </style>
  </head>
  <body>
    <canvas width="500" height="500" id="canvas"></canvas>
    <script>

      var canva = document.getElementById("canvas");
      var ctx = canva.getContext("2d");
    
      
      
       ctx.arc(170,170, 50, 0 , 180);
      ctx.fill();
 
    </script>

  </body>
</html>

проблема именно с параметрами startAngle и endAngle , если startAngle = 0 , а endAngle = 360 - то это будет круг , а если endAngle = 180 - то это полу-круг .
Но как бы я не менял параметр endAngle все равно рисует круг.
Где я туплю?

dmitriymar 14.11.2012 17:50

cyber,
углы в радианах а не в градусах радианы = (Math.PI/180)*градусы

cyber 14.11.2012 17:58

dmitriymar,
черт точно, за втыкал, спасибо.

cyber 14.11.2012 20:57

хм.. , еще не совсем понятно, почему рисует именно с правого края?
<!DOCTYPE HTML>
<html>
  <head>
    <style>
      canvas {
      
        border:1px solid black;
      }
    
    </style>
  </head>
  <body>
    <canvas width="500" height="500" id="canvas"></canvas>
    <script>

      var canva = document.getElementById("canvas");
      var ctx = canva.getContext("2d");
      ctx.width = 500;
      ctx.height = 500;
      
      var up = 360/60, angle = 0;
      
       
      
    !function timer() {
      
      if(angle == 360) return;
      
      angle += up;
      
      ctx.fillStyle = "red";
   
       ctx.arc(100,100, 40, 0,(Math.PI/180)* angle);
      ctx.fill();
      ctx.beginPath();
   
      
   
      
      setTimeout(timer,60);
      
      }();


    </script>

  </body>
</html>

melky 14.11.2012 23:11

Цитата:

Сообщение от cyber
хм.. , еще не совсем понятно, почему рисует именно с правого края?

потому что (0;0) находится слева сверху.

cyber 15.11.2012 01:49

melky, 0,0 находиться по центру.

cyber 15.11.2012 01:52

melky,
<!DOCTYPE HTML>
<html>
  <head>
    <style>
      canvas {
      
        border:1px solid black;
      }
    
    </style>
  </head>
  <body>
    <canvas width="500" height="500" id="canvas"></canvas>
    <script>

      var canva = document.getElementById("canvas");
      var ctx = canva.getContext("2d");
      ctx.width = 500;
      ctx.height = 500;
      var radius = 40;
    
      ctx.arc(100,0,radius,0 , (Math.PI/180)* 360);
      ctx.fill();
      ctx.beginPath();
       
      ctx.arc(200,radius,radius,0 , (Math.PI/180)* 360);
      ctx.fill();
      ctx.beginPath();
    

    </script>

  </body>
</html>

если бы он был с лева в верху то мне можно было смело идти переписывать 70% логики моего арканоида)

Дзен-трансгуманист 15.11.2012 03:10

cyber,
Сделай мячик спрайтом и не ипи себе мозг. =)

BTW, указывай параметр anticlockwise, пожалуйста, а то не везде без него работает.

Дзен-трансгуманист 15.11.2012 03:14

Цитата:

Сообщение от melky
потому что (0;0) находится слева сверху.

Ага, если только translate не применял. ;)

cyber 15.11.2012 10:35

Дзен-трансгуманист, да с мячиком проблема нет, просто хотел сделать анимацию загрузки таким вот извращенным способом но почему она видет себя так понять не могу.
А насчет параметра anticlockwise - яего указываю просто тестовый пример по быстрому писался ,как всегда.)

melky 15.11.2012 17:34

Цитата:

Сообщение от cyber (Сообщение 216062)
melky, 0,0 находиться по центру.

антитеза какая-то - начало координат находится в центре!

надеюсь, картинка прояснит :


немного поменял твой код - рисуется окружность в (0;0)
Цитата:

Сообщение от cyber (Сообщение 216064)
melky,
<!DOCTYPE HTML>
<html>
  <head>
    <style>
      canvas {
      
        border:1px solid black;
      }
    
    </style>
  </head>
  <body>
    <canvas width="500" height="500" id="canvas"></canvas>
    <script>

      var canva = document.getElementById("canvas");
      var ctx = canva.getContext("2d");
      ctx.width = 500;
      ctx.height = 500;
      var radius = 40;
    
      ctx.arc(0,0,radius,0 , (Math.PI/180)* 360);
      ctx.fill();
      ctx.beginPath();
       

    </script>

  </body>
</html>

Цитата:

Сообщение от cyber (Сообщение 216064)
если бы он был с лева в верху то мне можно было смело идти переписывать 70% логики моего арканоида)

мне жаль, что так вышло :D

Цитата:

Сообщение от Дзен-трансгуманист (Сообщение 216072)
Ага, если только translate не применял. ;)

или мы про разные начала говорим?

cyber 15.11.2012 17:46

melky, почитай спецификацию;)

cyber 15.11.2012 17:47

melky,это не спецификация но все же https://developer.mozilla.org/ru/doc...B3%D1%83%D1%80
Цитата:

Сообщение от developer.mozilla.org
Этот метод принимает пять параметров: x и y это координаты центра круга.


melky 15.11.2012 17:51

Цитата:

Сообщение от cyber
melky, почитай спецификацию

спека:
Цитата:

Начало координат этой сетки расположено в верхнем левом углу (координата (0,0)).
в метод arc передаются координаты центра дуги.

что почитать то?

Цитата:

Сообщение от cyber
melky, 0,0 находиться по центру.


cyber 15.11.2012 17:54

melky, для обычных дом элементов да, но не для круга на canvas , метод arc:
Цитата:

Этот метод принимает пять параметров: x и y это координаты центра круга

melky 15.11.2012 19:11

Цитата:

Сообщение от cyber (Сообщение 216163)
melky, для обычных дом элементов да, но не для круга на canvas , метод arc:

см. пост #11

cyber 15.11.2012 19:31

melky, и в посте 11 той код прикрасно доказывает что координаты задаются от центра круга.

Дзен-трансгуманист 15.11.2012 21:23

Цитата:

Сообщение от melky
Цитата:

Сообщение от Дзен-трансгуманист
Цитата:

Сообщение от melky
потому что (0;0) находится слева сверху.

Ага, если только translate не применял.

или мы про разные начала говорим?

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      canvas { border: 1px solid black; }
    </style>
    <script>
      onload = function () {
        var canva = document.getElementById("canvas");
        var ctx = canva.getContext("2d");

*!*
        ctx.translate(canva.width / 2, canva.height / 2);
*/!*
        ctx.arc(0, 0, 40, 0, (Math.PI / 180) * 360, true);
        ctx.fill();
      }
    </script>
  </head>
  <body>
    <canvas width="500" height="500" id="canvas"></canvas>
  </body>
</html>

melky,
cyber пытается сказать тебе, что точка (0, 0) в arc будет в фокусе дуги, а не слева сверху от нее.)
Вам надо поработать над взаимопониманием.)

Дзен-трансгуманист 15.11.2012 23:00

Цитата:

Сообщение от cyber
просто хотел сделать анимацию загрузки таким вот извращенным способом но почему она видет себя так понять не могу.


Окей, не уверен, какого ты хотел достичь эффекта, но например вот:

<!DOCTYPE HTML>
<html>
<head>
<style>
canvas { border: 1px solid black; }
</style>
<script>

function progressFn ( canvas ) {

  var ctx = canvas.getContext( "2d" );
  var cx = canvas.width / 2;
  var cy = canvas.height / 2;
  var radius = 50;

  var clearX = Math.floor( cx - radius );
  var clearY = Math.floor( cy - radius );
  var clearW = Math.ceil( cx + radius ) - clearX;
  var clearH = Math.ceil( cy + radius ) - clearY;

  return function ( progress ) {

    ctx.clearRect( clearX, clearY, clearW, clearH );
    ctx.save();

    ctx.globalCompositeOperation = "source-over";
    ctx.fillStyle = "hsl(120, 80%, 25%)";
    ctx.moveTo( cx, cy );
    ctx.arc( cx, cy, radius, 0, Math.PI * 2 * progress, false );
    ctx.fill();

    ctx.globalCompositeOperation = "xor";
    ctx.font = "bold 20px sans-serif";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText( ( progress * 100 ).toFixed( 0 ) + "%", cx, cy );

    ctx.restore();
  }
}

window.onload = function () {

  var progress = 0;
  var progressMax = 100;
  var showProgress = progressFn( document.getElementById( "canvas" ) );

  var interval = setInterval( function () {

    showProgress( progress / progressMax );
    if ( ++progress > progressMax ) {
      clearInterval( interval );
    }
  }, 50);
}

</script>
</head>
<body>
<canvas width="200" height="200" id="canvas"></canvas>
</body>
</html>

cyber 16.11.2012 01:51

Дзен-трансгуманист,тут суть не в том что я не могу анимацию сделать, мне просто интересно почему именно от туда начинаеться и как можно поменять точку начала рисования..

Дзен-трансгуманист 16.11.2012 02:36

Цитата:

Сообщение от cyber
почему именно от туда начинаеться и как можно поменять точку начала рисования

Ты мой код читал?
А спецификацию?
Неужели ни то, ни другое?

Дзен-трансгуманист 16.11.2012 03:05

Цитата:

Сообщение от cyber
почему рисует именно с правого края?

Потому что угол 0 - это когда вправо! Ты же сам передаешь ноль в тот аргумент - что тут, блин, непонятного?!

Цитата:

Сообщение от http://www.w3.org/TR/2011/WD-2dcontext-20110525/#dom-context-2d-arc
The points at startAngle and endAngle along this circle's circumference, measured in radians clockwise from the positive x-axis, are the start and end points respectively.


Будь добр, когда спрашиваешь о чем-то - не игнорируй ссылки, которые тебе дают.

cyber 16.11.2012 03:19

Дзен-трансгуманист, сори, весь день седня на тормозе...

Дзен-трансгуманист 16.11.2012 10:18

cyber,
Спеку по Canvas 2D Context реально осилить за 3 дня, если все прочитываемое пробовать сразу же на практике.
То есть, это конечно не значит, что за 3 дня ты всё это впечатаешь себе в мозг как азбуку, но по крайней мере будешь понимать, что к чему и почему.

Ну и, извини конечно, но даже школьнику должно быть известно, что 0° - это вперед по оси X, 90° - вперед по оси Y, и т.д.
Везде и всегда так было, а не только в канвасе. :)

cyber 16.11.2012 10:24

Дзен-трансгуманист, я знаю говорю же на тормозе был, седня буду в спеке дальше разбираться.

dmitriymar 16.11.2012 12:19

ответ попроще на самом деле . сектор круга это не 0 - 2PI , а -PI - +PI как и во всех тригонометрических операциях языка

cyber 16.11.2012 14:46

Дзен-трансгуманист, спасибо твой код помог(особенно moveTo как то не додумался до этого), я вчера жестоко тупил и не пойму с какого перепугу мне вчера казалось что 0 градусов этой прямой угол, в данный момент я понимаю нужно начинать с -90 градусов, но вчера меня жестоко плющило (просто почти не спал вчера).
ctx.arc(150,150,40, -(Math.PI/180)*90,(Math.PI/180)*i,false);


<!DOCTYPE HTML>
<html>
  <head> </head>
  <body>
    <canvas width="500" height="500"></canvas>
    <script>
var canva = document.body.children[0];
      
      var ctx = canva.getContext("2d");
      
      
      var i = -90;
      
      !function drawArc() {
      
       
         if(i>270)return;
        
        
        ctx.clearRect(110,110,80,80);
        ctx.moveTo( 150, 150 );
        ctx.arc(150,150,40, -(Math.PI/180)*90,(Math.PI/180)*i,false);
       ctx.fill();
      ctx.beginPath();
      
      i+=5;
        
        setTimeout(drawArc,60) 
      }();



    </script>

  </body>
</html>

cyber 16.11.2012 17:24

может кто то подкинет идейку, осталось в игре до пилить так что бы проверялись координаты мячика а не его крайняя точка по х , т.е
<!DOCTYPE HTML>
<html>
  <head> </head>
  <body>
    <canvas width="500" height="500"></canvas>
    
    <script>

var canva = document.body.children[0];
   var ctx = canva.getContext("2d");   
      
      ctx.fillStyle = "green";
      ctx.strokeRect(50,50,100,100);
      ctx.beginPath();
      
      
      ctx.fillStyle="red";
      ctx.arc(100,100,50,0,(Math.PI/180)*360, false);
      ctx.fill();
      ctx.beginPath();

    </script>

  </body>
</html>


в данный момент сделано так что к х прибавляется или отнимается радиус но так не красиво выглядит когда мячик пролетает очень близко , а условие срабатывает из за того что зацепился углом, не могу придумать как сделать так что проверялись координаты мяча без учета пустого пространства.
Может кто подкинет идейку?

melky 16.11.2012 17:45

Цитата:

Сообщение от cyber
может кто то подкинет идейку, осталось в игре до пилить так что бы проверялись координаты мячика а не его крайняя точка по х , т.е

принадлежность точки окружности => расстояние от точки до центра меньше или равно радиусу.
var radius = 10; // радиус окружности

var center = [ 5, 5 ]; // точка центра окружности

var point = [ 0, 0 ]; // точка, принадлежность которой определяем

// координаты вектора из точки к центру окружности
var x = point[0] - center[0];
var y = point[1] - center[1];

// модуль этого вектора
var distance = Math.sqrt(x*x + y*y);

// принадлежит ли (bool)
var belongs = distance <= radius;

cyber 16.11.2012 21:06

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

cyber 17.11.2012 15:39

melky, опять спустя день понял в чем фишка, спс.
На ночь лучше не думать и не писать)

cyber 17.11.2012 22:05

блин, запутался шарик может столкнуться с блоком в любой его точке, а так как мячик может находиться на нескольких строках одновременно
поэтому есть вариант:
проверять все точки окружность которые находятся в данной точке на совпадения с координатами блока, но как их получать за кэшировать или каждый раз определять...

буду благодарен за любые подсказки...

Дзен-трансгуманист 17.11.2012 23:13

cyber,
В случае с шариком, коллизии и углы отражения становится считать легче, если на уровне логики движка принять шарик за материальную точку, а фигуры расширить радиально на величину радиуса шарика.

melky 18.11.2012 00:18

cyber, опять постишь на ночь? или это я уже туплю .. при чём тут строки? что это? почему нельзя определять принадлежность каждой крайней точки (top left; top right; bottom left; bottom right) к окружности (шарику) ?

cyber 18.11.2012 01:29

melky, шарик может не только с крайней точкой соприкоснуться а и в любом другом месте допустим он зацепит нижней частью блок , вот 2 варианта

и тогда прийдеться проверять все точки вокруг блока..

cyber 18.11.2012 01:31

Дзен-трансгуманист, не совсем понял, если их разширить то тогда шарик будет на фигуре то будет ее затирать по ходу смещения, а если увеличить просто размеры обьектов то он начнет их уничтожать до визуального контакта..

Дзен-трансгуманист 18.11.2012 04:40

cyber,
Да нет же! Для игрока всё визуально остается без изменений. Я просто иллюстрирую как должен выглядеть механизм обработки столкновений изнутри.


Столкновения с углами - самые сложные. Я тебе специально изобразил эту механическую симметрию. Там, где ты видишь скругления - это просто окружности, центр каждой из которых находится в одном из исходных углов, и три четверти которых скрыты под внешними горизонтальными и вертикальными отрезками. Когда точка падает на такую окружность, отражение легко посчитать: нужно просто вычислить направление нормали (радиус-вектора) в точке соприкосновения, обратить направление падения и зеркально отразить его от нормали.
Касательную я изобразил просто для наглядности принципа, известного как "угол отражения равен углу падения". А нормаль выходит наружу под прямым углом к этой касательной, то есть это просто вектор, направленный из центра окружности к нашей точке в момент их столкновения.

Вот. А теперь докажи мне на практике, что мои труды по рисованию не были бесполезны - а не то я разозлюсь и сделаю свой собственный арканоид! :)

cyber 18.11.2012 14:08

Дзен-трансгуманист, спасибо, буду вспоминать геометрию
Цитата:

Вот. А теперь докажи мне на практике, что мои труды по рисованию не были бесполезны - а не то я разозлюсь и сделаю свой собственный арканоид!
все будет в лучшем виде))

Дзен-трансгуманист 18.11.2012 22:45

Цитата:

Сообщение от cyber
буду вспоминать геометрию

Да в сети есть куча ресурсов и форумов, где конкретно эта тема столкновений в 2D разжевывается раз в сто лучше, чем могу разжевать я. Можно на том же геймдеве поискать.
Супер-оптимизаций никто от тебя не требует, просто организуй всё так, чтобы хотя бы не тормозило.))

melky 18.11.2012 22:54

Цитата:

Сообщение от Дзен-трансгуманист
Да в сети куча ресурсов и форумов, где конкретно эта тема столкновений в 2D разжевывается раз в сто лучше, чем могу разжевать я. Можно на том же геймдеве поискать. Тебе же просто нужно организовать всё так, чтобы хотя бы не тормозило.)

http://www.gamedev.ru/code/forum/?id=147255&page=3

классный ресурс, кстати


Часовой пояс GMT +3, время: 09:26.