Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript画布中绘制圆弧起点、半径和终点_Javascript_Html_Canvas_Html5 Canvas - Fatal编程技术网

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

在JavaScript画布中绘制圆弧起点、半径和终点,javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,我需要画一条有起始点,半径和终点的弧 我在JavaScript中使用HTML5画布弧函数(x、y、radius、startAngle、endAngle、逆时针) (x,y,半径,星形,端角,逆时针) 拥有: 预期结果: 请提供一些帮助您需要做一点数学运算才能找到符合您的3个约束条件的圆心: •与初始点相交 •与最终点相交 •提供了半径 请注意,可能没有结果:如果点之间的距离是半径的两倍,则没有圆可以匹配。 如果点距离小于2*半径,我们有两个结果事实上,我不知道您希望您的用户如何选择 数学使用了

我需要画一条有起始点,半径和终点的弧

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

(x,y,半径,星形,端角,逆时针)

拥有:

预期结果:


请提供一些帮助

您需要做一点数学运算才能找到符合您的3个约束条件的圆心:
•与初始点相交
•与最终点相交
•提供了半径

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

数学使用了几个属性:
•圆心位于与p1、p2垂直的线上。
•pm,(p1,p2)的中点也是(c1,c2)的中点。
•三角形(p1、pm、c1)和(p1、pm、c2)在pm中有90°角(法语称为“三角形矩形”,英语称为donno)

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

核心职能:

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

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


你必须做一点数学运算,才能找到与你的3个约束条件相匹配的圆心:
•与初始点相交
•与最终点相交
•提供了半径

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

数学使用了几个属性:
•圆心位于与p1、p2垂直的线上。
•pm,(p1,p2)的中点也是(c1,c2)的中点。
•三角形(p1、pm、c1)和(p1、pm、c2)在pm中有90°角(法语称为“三角形矩形”,英语称为donno)

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

核心职能:

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

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


如果有人在SVG中寻找等价物(使用D3.js),请使用:

函数极坐标(centerX、centerY、半径、角度等){
var angleInRadians=(angleInDegrees-90)*Math.PI/180.0;
返回{
x:centerX+(半径*数学坐标(角半径)),
y:中心y+(半径*数学正弦(角度半径))
};
}
函数描述C(x,y,半径,星形,端角){
var起点=极笛卡尔坐标(x,y,半径,端角);
var end=极笛卡尔坐标(x,y,半径,星形);

var arcSweep=endAngle-startAngle如果有人在SVG中寻找等价物(使用D3.js),请使用:

函数极坐标(centerX、centerY、半径、角度等){
var angleInRadians=(angleInDegrees-90)*Math.PI/180.0;
返回{
x:centerX+(半径*数学坐标(角半径)),
y:中心y+(半径*数学正弦(角度半径))
};
}
函数描述C(x,y,半径,星形,端角){
var起点=极笛卡尔坐标(x,y,半径,端角);
var end=极笛卡尔坐标(x,y,半径,星形);

var arcSweep=endAngle-startAngle
context。如果所需半径为40,则弧
永远不会绘制连接初始点和最终点的弧。通过这两个点的弧为80。请记住
context.arc
将始终绘制一个部分圆,以便曲线不会“弯曲”在这两点之间延伸。正如你在上一个问题中所建议的那样……使用
context.quadraticCurveTo
来“弯曲”两个点之间的曲线。;-
上下文。如果所需半径为40,则弧
将永远不会绘制连接初始点和最终点的弧。通过这两个点的弧为80。请记住
上下文。弧
将始终绘制一个部分圆,以便曲线不会“弯曲”在这两点之间延伸。正如你在上一个问题中所建议的那样……使用
context.quadraticCurveTo
来“弯曲”两个点之间的曲线。;-)不客气。我的伪玩家是游戏炼金术士,我相信你可以花费所需的时间全部键入。关于你的问题,如果我猜得好的话,是关于知道要绘制弧的哪一侧,在这种情况下,你可以1)让用户给出第三个点,指示弧应该位于的空间部分。2)考虑按照惯例,弧应始终位于p1p2的左侧。在这种情况下,Rq的顺序为(p1,p2)matters.mmm第二个想法我想布尔参数left/right是一个更好的选择。输入是P1,P2,R,side。只需更改我的代码,在drawCircleArc中,var顺时针=side;并且只使用c1,第一个计算圆心。请参阅我的编辑。不客气。我的伪参数是GameAlchemist,我相信您可以花时间键入alL.关于你的问题,如果我猜得好,那就要知道弧的哪一边画出,在这种情况下,你可以1)让用户给出一个第三点来指示圆弧应该在哪里的空间。2)根据惯例考虑弧应该总是在P1P2的左边。RQ,在这种情况下,(P1,P2)的顺序。matters.mmm再想一想,我想布尔参数left/right是一个更好的选择。输入是P1,P2,R,side。只需更改我的代码,在drawCircleArc中,var顺时针=side;并且只使用c1,第一个计算出的圆心。请参阅我的编辑。
//
function findCenters(r, p1, p2) {
  // pm is middle point of (p1, p2)
  var pm = { x : 0.5 * (p1.x + p2.x) , y: 0.5*(p1.y+p2.y) } ;
  drawPoint(pm, 'PM (middle)');
  // compute leading vector of the perpendicular to p1 p2 == C1C2 line
  var perpABdx= - ( p2.y - p1.y );
  var perpABdy = p2.x - p1.x;
  // normalize vector
  var norm = Math.sqrt(sq(perpABdx) + sq(perpABdy));
  perpABdx/=norm;
  perpABdy/=norm;
  // compute distance from pm to p1
  var dpmp1 = Math.sqrt(sq(pm.x-p1.x) + sq(pm.y-p1.y));
  // sin of the angle between { circle center,  middle , p1 } 
  var sin = dpmp1 / r ;
  // is such a circle possible ?
  if (sin<-1 || sin >1) return null; // no, return null
  // yes, compute the two centers
  var cos = Math.sqrt(1-sq(sin));   // build cos out of sin
  var d = r*cos;
  var res1 = { x : pm.x + perpABdx*d, y: pm.y + perpABdy*d };
  var res2 = { x : pm.x - perpABdx*d, y: pm.y - perpABdy*d };
  return { c1 : res1, c2 : res2} ;  
}
function sq(x) { return x*x ; }

function drawPoint(p, name) {
  ctx.fillRect(p.x - 1,p.y - 1,2, 2);
  ctx.textAlign = 'center';
  ctx.fillText(name, p.x, p.y+10);
}

function drawCircle(c, r) {
  ctx.beginPath();
  ctx.arc(c.x, c.y, r, 0, 6.28);
  ctx.strokeStyle='#000';
  ctx.stroke();
}

function drawCircleArc(c, r, p1, p2, col) {
  var ang1 = Math.atan2(p1.y-c.y, p1.x-c.x);
  var ang2 = Math.atan2(p2.y-c.y, p2.x-c.x);
  ctx.beginPath();
  var clockwise = ( ang1 > ang2);
  ctx.arc(c.x, c.y, r, ang1, ang2, clockwise);
  ctx.strokeStyle=col;
  ctx.stroke();
}
function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
  var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

  return {
    x: centerX + (radius * Math.cos(angleInRadians)),
    y: centerY + (radius * Math.sin(angleInRadians))
  };
}

function describeArc(x, y, radius, startAngle, endAngle){
    var start = polarToCartesian(x, y, radius, endAngle);
    var end = polarToCartesian(x, y, radius, startAngle);
    var arcSweep = endAngle - startAngle <= 180 ? "0" : "1";
    var d = [
        "M", start.x, start.y, 
        "A", radius, radius, 0, arcSweep, 0, end.x, end.y
    ].join(" ");
    return d;       
}

function sq(x) { return x*x ; }

function drawCircleArcSVG(c, r, p1, p2, col) {
  var ang1 = Math.atan2(p1.y-c.y, p1.x-c.x)*180/Math.PI+90;
  var ang2 = Math.atan2(p2.y-c.y, p2.x-c.x)*180/Math.PI+90;
  var clockwise = side;
  var path = describeArc(c.x, c.y, r, ang1, ang2)
  console.log(path)
  svg.append("path").attr("d", path).attr("fill", "none").attr("stroke-width", 3).attr("stroke", col)
}

function drawPointSVG(p, name) {
    svg.append("circle").attr("cx", p.x).attr("cy", p.y).attr("r", 2)
    svg.append("text").attr("x", p.x).attr("y", p.y+10).style("font-size", 10).text(name).style("font-family", "Arial")
}

function drawCircleSVG(c, r) {
    svg.append("circle").attr("cx", c.x).attr("cy", c.y).attr("r", r).style("fill", "none").attr("stroke", "#000")
}