Рисуем на canvas веер из хорд в окружности
Понадобилось в работе, оставлю памятку.
"Веер" задан количеством лучей N
и углом раствора лучей theta
, начальная точка испускания лучей - крайняя правая точка окружности с координатами (width, cy)
, в которую переносится начало координат, но можно проделать аналогичные расчёты и для другой точки.
Вот какая картинка получается:
веер из хорд на canvas, скриншот
Расчёты сводятся к тому, чтобы по начальному углу отрисовки луча alpha0
(задан в градусах) получить центральный угол хорды alpha
и затем по известной формуле вычислить её длину l
. После этого для отрисовки очередного луча достаточно перевести полярные координаты (alpha0,l)
в декартовы и соединить две точки линией.
В расчётах нужно учесть, что Javascript по умолчанию предполагает, что мы измеряем углы по часовой стрелке, а не против, как обычно.
Вот исходник примера, который может быть выполнен в браузере как файл типа .html
:
<meta charset="windows-1251"> <div align="center"> <canvas id="canvas" width="600" height="600" style="background-color: white; border: 1px dotted lightgray; padding: 4px;"> </canvas> </div> <script> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var width = canvas.width; var height = canvas.height; //размеры канвы var cx = Math.floor(width/2); var cy = Math.floor(height/2); //центр канвы ctx.clearRect(0, 0, width, height); //окружность ctx.strokeStyle = 'rgba(0, 0, 0, 255)'; var rad = Math.floor(Math.min(width,height)/2); ctx.beginPath(); ctx.arc(cx, cy, rad, 0, Math.PI * 2, true); ctx.stroke(); //оси ctx.strokeStyle = 'rgba(255, 0, 0, 255)'; ctx.beginPath(); ctx.moveTo (0, cy); ctx.lineTo (width, cy); ctx.moveTo (width-8, cy-8); ctx.lineTo (width, cy); ctx.moveTo (width-8, cy+8); ctx.lineTo (width, cy); ctx.moveTo (cx, cy); ctx.lineTo (cx, 0); ctx.moveTo (cx-8, 8); ctx.lineTo (cx, 0); ctx.moveTo (cx+8, 8); ctx.lineTo (cx, 0); ctx.stroke(); //подписи ctx.fillStyle = 'rgba(0, 0, 255, 255)'; ctx.font = "14px Arial"; ctx.fillText("0", cx-4, cy+14); ctx.fillText("X", width-18, cy+14); ctx.fillText("Y", cx+8, 14); ctx.fillText("R", cx+8, cy/2); //лучи ctx.strokeStyle = 'rgba(0, 255, 0, 255)'; ctx.save(); ctx.translate(width, cy); //перенос начала координат в точку испускания лучей ctx.beginPath(); var N = 31, theta=120, startC = 120; //количество лучей, угол раствора, начальный угол //меряет углы по часовой стрелке! var stepC = theta/N; for (var n=0; n<N; n++) { var alpha0 = startC + n * stepC; //угол отрисовки в градусах var alpha = 180 - 2 * (180 - alpha0); //центральный угол хорды в градусах var l = 2 * rad * Math.sin (alpha/2 * (Math.PI/180)); //длина хорды ctx.moveTo (0, 0); ctx.lineTo ( Math.round (l * Math.cos(alpha0 * (Math.PI/180))), Math.round (l * Math.sin(alpha0 * (Math.PI/180))) ); } ctx.stroke(); ctx.restore(); </script> <noscript> <div align="center"> Извините, нужен Javascript для работы приложения </div> </noscript>
05.02.2019, 15:51 [1685 просмотров]