在 JavaScript Canvas 中绘制圆弧起点、半径和终点

1 html javascript canvas html5-canvas

我需要绘制一个具有起点、半径和终点的圆弧。

我在 JavaScript 中使用 HTML5 画布弧函数(x、y、半径、startAngle、endAngle、逆时针)。

context.arc(x,y,半径,startAngle,endAngle,逆时针)

有:

var initialPoint = { x: 20, y: 40 };
var radius = 40;
var finalPoint = { x: 180, y: 40 };
Run Code Online (Sandbox Code Playgroud)

预期结果:

样品

请帮忙

Gam*_*ist 6

您必须做一些数学运算才能找到与 3 个约束匹配的圆心:
\n\xe2\x80\xa2 与 initialPoints 相交
\n\xe2\x80\xa2 与 FinalPoint 相交
\n\xe2\x80\xa2已提供半径

\n\n

请注意,可能没有结果:如果点之间的距离是彼此半径两倍的距离,则没有圆可以匹配。
\n如果点的距离 < 2 * 半径,实际上我们有两个结果,我不知道您希望用户如何选择。

\n\n

数学使用了一些属性:
\n\xe2\x80\xa2 圆心位于垂直于 p1、p2 的线上。
\n\xe2\x80\xa2 pm,(p1,p2)的中点也是(c1,c2)的中点。
\n\xe2\x80\xa2 三角形 (p1, pm, c1) 和 (p1, pm, c2) 在 pm 中的角度为 90\xc2\xb0 (法语中称为“三角矩形”,英语中称为 donno) 。

\n\n

这是一个屏幕截图,其中有绿色/红色的两个可能的弧线:

\n\n

在此输入图像描述

\n\n

http://jsbin.com/jutidigepeta/1/edit?js,输出

\n\n
var initialPoint = { x: 100, y: 160 };\nvar radius = 90;\nvar finalPoint = { x: 240, y: 190 };\n\nvar centers = findCenters(radius,initialPoint, finalPoint );\n
Run Code Online (Sandbox Code Playgroud)\n\n

核心功能:

\n\n
//\nfunction findCenters(r, p1, p2) {\n  // pm is middle point of (p1, p2)\n  var pm = { x : 0.5 * (p1.x + p2.x) , y: 0.5*(p1.y+p2.y) } ;\n  drawPoint(pm, \'PM (middle)\');\n  // compute leading vector of the perpendicular to p1 p2 == C1C2 line\n  var perpABdx= - ( p2.y - p1.y );\n  var perpABdy = p2.x - p1.x;\n  // normalize vector\n  var norm = Math.sqrt(sq(perpABdx) + sq(perpABdy));\n  perpABdx/=norm;\n  perpABdy/=norm;\n  // compute distance from pm to p1\n  var dpmp1 = Math.sqrt(sq(pm.x-p1.x) + sq(pm.y-p1.y));\n  // sin of the angle between { circle center,  middle , p1 } \n  var sin = dpmp1 / r ;\n  // is such a circle possible ?\n  if (sin<-1 || sin >1) return null; // no, return null\n  // yes, compute the two centers\n  var cos = Math.sqrt(1-sq(sin));   // build cos out of sin\n  var d = r*cos;\n  var res1 = { x : pm.x + perpABdx*d, y: pm.y + perpABdy*d };\n  var res2 = { x : pm.x - perpABdx*d, y: pm.y - perpABdy*d };\n  return { c1 : res1, c2 : res2} ;  \n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

公用事业:

\n\n
function sq(x) { return x*x ; }\n\nfunction drawPoint(p, name) {\n  ctx.fillRect(p.x - 1,p.y - 1,2, 2);\n  ctx.textAlign = \'center\';\n  ctx.fillText(name, p.x, p.y+10);\n}\n\nfunction drawCircle(c, r) {\n  ctx.beginPath();\n  ctx.arc(c.x, c.y, r, 0, 6.28);\n  ctx.strokeStyle=\'#000\';\n  ctx.stroke();\n}\n\nfunction drawCircleArc(c, r, p1, p2, col) {\n  var ang1 = Math.atan2(p1.y-c.y, p1.x-c.x);\n  var ang2 = Math.atan2(p2.y-c.y, p2.x-c.x);\n  ctx.beginPath();\n  var clockwise = ( ang1 > ang2);\n  ctx.arc(c.x, c.y, r, ang1, ang2, clockwise);\n  ctx.strokeStyle=col;\n  ctx.stroke();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑 :

\n\n

这里是一个使用“side”的小提琴,这是一个布尔值,表明我们应该选择弧线的哪一侧。

\n\n

http://jsbin.com/jutidigepeta/3/edit

\n