Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/430.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_Math_Geometry_Ellipse - Fatal编程技术网

Javascript 给定固定角度、宽度和;我们如何计算椭圆的水平和垂直半径?

Javascript 给定固定角度、宽度和;我们如何计算椭圆的水平和垂直半径?,javascript,math,geometry,ellipse,Javascript,Math,Geometry,Ellipse,给定一个固定的角度、宽度和矢状,我们如何计算椭圆的水平和垂直半径 我想画一条椭圆弧,它具有给定的弧宽、弧高(矢状)和椭圆的给定角度。 下图中为黑色和黄色虚线弧。要做到这一点,我需要知道椭圆的两个半径 对于一个圆,可以很容易地计算出它的1个半径,给出任意2个角度、矢状或宽度值。 请参阅下面的代码片段。 如何调整函数以适用于椭圆? 图中的角度可以说是对称的,从-60到60,角度为120。这是我真正需要的情况,即弧在垂直轴或水平轴的两侧反射自身。 如果角度是120,从80开始,到200结束,没有真正的

给定一个固定的角度、宽度和矢状,我们如何计算椭圆的水平和垂直半径

我想画一条椭圆弧,它具有给定的弧宽、弧高(矢状)和椭圆的给定角度。
下图中为黑色和黄色虚线弧。要做到这一点,我需要知道椭圆的两个半径

对于一个圆,可以很容易地计算出它的1个半径,给出任意2个角度、矢状或宽度值。
请参阅下面的代码片段。
如何调整函数以适用于椭圆? 图中的角度可以说是对称的,从-60到60,角度为120。这是我真正需要的情况,即弧在垂直轴或水平轴的两侧反射自身。
如果角度是120,从80开始,到200结束,没有真正的矢状图,只有弧的最高点和一个紧密的边界框,如果有人也有解决方案,这将是一种奢侈

var arcCalc=函数(r、w、a、s){
//允许对象使用
if(对象的r实例){
w=r.w | | r.宽度;
a=r.a | | r.角;
s=r.s | | r.sagitta;
r=r.r | | r.半径;
}
w=这个。toPts(w);
s=此。toPts(s);
r=这个。toPts(r);
var sin,cos,twoKnown;
sin=Math.sin;
cos=Math.cos;
//如果我们知道任何两个论点,那么我们就可以找出其他论点
//如果不是,我们不能
twoKnown=+!r++!w++!a++!s<3;
//此时,我们正试图避免抛出错误
//所以现在就把我们收到的垃圾扔回去吧
如果(!twoKnown)
返回{
半径:r,
宽度:w,
角度:a,,
萨吉塔:是的,
r:r,
w:w,
a:a,
s:s
};
如果(a){
a*=数学PI/180;
}
if(!r){
如果(!s){
r=w/(2*sin(a/2));
}否则如果(!a){
r=(s*s+0.5*w*(0.5*w))/(2*s);
}否则{
r=s/(1-cos(a/2));
}
}
//在这一点上,我们知道我们有r
如果(!w){
如果(!s){
w=2*r*sin(a/2);
}否则{
w=2*Math.sqrt(s*(2*r-s));
}
}
//在这一点上,我们知道我们有r和w
如果(!a){
如果(!s){
//我们加了一轮是因为
//w/(2*r)可能达到1.000000000001
//然后就产生了NaN
a=2*Math.asin(本轮(w/(2*r));
}否则{
a=2*Math.acos(本轮(1-s/r));
}
}
如果(!s){
s=r-r*cos(a/2);
}
a*=180/Math.PI;
返回{
半径:r,
宽度:w,
角度:a,,
萨吉塔:是的,
r:r,
w:w,
a:a,
s:s
};
};

给出的是角度α、宽度和矢状。圆的半径
r
可根据α和正弦公式计算。类似地,
x-sagitta
遵循余弦公式

为了找到
y
,我们使用
y/x
的因子将图形缩放到x方向。这会将椭圆转换为半径为y的圆。它将
[x-sagitta,width/2]
处的点转换为
[(x-sagitta)*y/x,width/2]
。该转换点必须位于半径为
y
的圆上。我们在
y
中得到一个二次方程:

((x-sagitta)*y/x)^2+(宽度/2)^2=y^2

其积极的解决办法是

y=width*x*sqrt(1/(矢状图*(2*x-sagitta))/2

前提是
2*x>sagitta
。它减少到
cos(alpha/2)>0
alpha<180°
。当然,矢状、宽度和阿尔法的极端组合会导致椭圆极度拉伸

继续,这将给出(r是圆的半径,x和y是椭圆的轴):

使用Python和matplotlib绘制所有内容可确保方程式有意义:

从matplotlib导入pyplot作为plt
从matplotlib.patches导入椭圆
从数学输入sqrt、sin、cos、atan、pi
矢状位=15
α=120*pi/180
宽度=100
r=宽度/2/sin(α/2)
x=r*cos(α/2)+sagitta
y=宽度*x/sqrt(矢状图*(2*x-矢状图))/2
ax=plt.gca()
ax.图([r*cos(alpha/2),0,r*cos(alpha/2)],[r*sin(alpha/2),0,r*sin(alpha/2)],ls='-',
颜色(深红色)
椭圆=椭圆((0,0),2*x,2*y,颜色=紫色,线宽=1,填充=假,ls='-'))
圆=椭圆((0,0),2*r,2*r,color='番茄',线宽=1,fill=False,ls='-'
lim=最大值(x,y)*1.05
最大设定值\u xlim(-lim,lim)
最大设定值_ylim(-lim,lim)
ax.axhline(0,color='silver')
ax.axvline(0,颜色='silver')
ax.plot([x-sagitta,x-sagitta],[width/2,-width/2],color='limegreen',ls='--'))
ax.plot([x-sagitta,x],[0,0],color='brown',ls=''-')
ax.添加补片(椭圆)
ax.添加补片(圆形)
ax.文本(x-sagitta,宽/2'[x-s,宽/2]')
ax.set_方面(1)
plt.show()

给定的是角度α、宽度和矢状。圆的半径
r
可根据α和正弦公式计算。类似地,
x-sagitta
遵循余弦公式

为了找到
y
,我们使用
y/x
的因子将图形缩放到x方向。这会将椭圆转换为半径为y的圆。它将
[x-sagitta,width/2]
处的点转换为
[(x-sagitta)*y/x,width/2]
。该转换点必须位于半径为
y
的圆上。我们在
y
中得到一个二次方程:

((x-sagitta)*y/x)^2+(宽度/2)^2=y^2

其积极的解决办法是

y=width*x*sqrt(1/(矢状图*(2*x-sagitta))/2

前提是
2*x>sagitta
。它减少到
cos(alpha/2)>0
alpha<180°
。当然是矢状、宽度和宽度的极端组合
var arcCalc = function(r, w, a, s) {
  // to allow for object usage
  if (r instanceof Object) {
    w = r.w || r.width;
    a = r.a || r.angle;
    s = r.s || r.sagitta;
    r = r.r || r.radius;
  }
  w = this.toPts(w);
  s = this.toPts(s);
  r = this.toPts(r);
  var sin, cos, twoKnown;
  sin = Math.sin;
  cos = Math.cos;
  // if we know any two arguments then we can work out the other ones
  // if not we can't
  twoKnown = +!r + +!w + +!a + +!s < 3;
  // At this point of time we are trying to avoid throwing errors
  // so for now just throw back the garbage we received
  if (!twoKnown)
    return {
      radius: r,
      width: w,
      angle: a,
      sagitta: s,
      r: r,
      w: w,
      a: a,
      s: s
    };
  if (a) {
    a *= Math.PI / 180;
  }

  if (!r) {
    if (!s) {
      r = w / (2 * sin(a / 2));
    } else if (!a) {
      r = (s * s + 0.5 * w * (0.5 * w)) / (2 * s);
    } else {
      r = s / (1 - cos(a / 2));
    }
  }
  // at this point we know we have r
  if (!w) {
    if (!s) {
      w = 2 * r * sin(a / 2);
    } else {
      w = 2 * Math.sqrt(s * (2 * r - s));
    }
  }
  // at this point we know we have r and w
  if (!a) {
    if (!s) {
      // We added the round because
      // w / (2*r) could come to 1.00000000001
      // and then NaN would be produced
      a = 2 * Math.asin(this.round(w / (2 * r)));
    } else {
      a = 2 * Math.acos(this.round(1 - s / r));
    }
  }
  if (!s) {
    s = r - r * cos(a / 2);
  }

  a *= 180 / Math.PI;
  return {
    radius: r,
    width: w,
    angle: a,
    sagitta: s,
    r: r,
    w: w,
    a: a,
    s: s
  };
};
r = width / 2 / sin(alpha / 2)
x = r * cos(alpha / 2) + sagitta
y = width * x / sqrt(sagitta * (2 * x - sagitta)) / 2