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)
预期结果:

请帮忙
您必须做一些数学运算才能找到与 3 个约束匹配的圆心:
\n\xe2\x80\xa2 与 initialPoints 相交
\n\xe2\x80\xa2 与 FinalPoint 相交
\n\xe2\x80\xa2已提供半径
请注意,可能没有结果:如果点之间的距离是彼此半径两倍的距离,则没有圆可以匹配。
\n如果点的距离 < 2 * 半径,实际上我们有两个结果,我不知道您希望用户如何选择。
数学使用了一些属性:
\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
http://jsbin.com/jutidigepeta/1/edit?js,输出
\n\nvar initialPoint = { x: 100, y: 160 };\nvar radius = 90;\nvar finalPoint = { x: 240, y: 190 };\n\nvar centers = findCenters(radius,initialPoint, finalPoint );\nRun 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}\nRun Code Online (Sandbox Code Playgroud)\n\n公用事业:
\n\nfunction 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}\nRun Code Online (Sandbox Code Playgroud)\n\n编辑 :
\n\n这里是一个使用“side”的小提琴,这是一个布尔值,表明我们应该选择弧线的哪一侧。
\n\nhttp://jsbin.com/jutidigepeta/3/edit
\n| 归档时间: |
|
| 查看次数: |
3309 次 |
| 最近记录: |